Skip to content

Commit

Permalink
Merge pull request #311 from alebedev87/hsts-and-config-parser
Browse files Browse the repository at this point in the history
router test: config template: don't match against the whole file
  • Loading branch information
openshift-merge-robot authored Sep 6, 2021
2 parents 2d1e1f4 + a4f8427 commit 6316ee7
Show file tree
Hide file tree
Showing 338 changed files with 30,835 additions and 451 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ require (
github.com/getsentry/raven-go v0.2.0 // indirect
github.com/gocarina/gocsv v0.0.0-20190927101021-3ecffd272576
github.com/google/go-cmp v0.5.2
github.com/haproxytech/config-parser/v4 v4.0.0-rc1
github.com/openshift/api v0.0.0-20210414143350-f71e361ed3f4
github.com/openshift/client-go v0.0.0-20201214125552-e615e336eb49
github.com/openshift/library-go v0.0.0-20201223214116-830765adf874
Expand Down
15 changes: 12 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,8 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me
github.com/gobuffalo/flect v0.2.0/go.mod h1:W3K3X9ksuZfir8f/LrfVtWmCDQFfayuylOJ7sz/Fj80=
github.com/gocarina/gocsv v0.0.0-20190927101021-3ecffd272576 h1:nDMaZgjBNKhsVJEWN1wAnqUJWwWGxFdDlt8U17KqMQ8=
github.com/gocarina/gocsv v0.0.0-20190927101021-3ecffd272576/go.mod h1:/oj50ZdPq/cUjA02lMZhijk5kR31SEydKyqah1OgBuo=
github.com/gofrs/flock v0.8.0 h1:MSdYClljsF3PbENUUEx85nkWfJSGfzYI9yEBZOJz6CY=
github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
Expand Down Expand Up @@ -286,6 +288,8 @@ github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hf
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/renameio v0.1.1-0.20200217212219-353f81969824 h1:9q700G0beHecUuiZOuKgNqNsGQixTeDLnzVZ5nsW3lc=
github.com/google/renameio v0.1.1-0.20200217212219-353f81969824/go.mod h1:t/HQoYBZSsWSNK35C6CO/TpPLDVWvxOHboWUAweKUpk=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
Expand Down Expand Up @@ -313,6 +317,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-gateway v1.9.5 h1:UImYN5qQ8tuGpGE16ZmjvcTtTw24zw1QAp/SlnNrZhI=
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/haproxytech/config-parser/v4 v4.0.0-rc1 h1:7F7v1AipK89ox0M2P96NnM1ZMAj152Yoc43aQf2Zx+E=
github.com/haproxytech/config-parser/v4 v4.0.0-rc1/go.mod h1:R2KvNW3R5pf+ucN4K0Wtdhib08U8L10rRAwP2lEDuWQ=
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
Expand Down Expand Up @@ -363,6 +369,8 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxv
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
Expand Down Expand Up @@ -411,7 +419,6 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
Expand Down Expand Up @@ -699,8 +706,9 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 h1:8qxJSnu+7dRq6upnbntrmriWByIakBuct5OM/MdQC1M=
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210319071255-635bc2c9138d h1:jbzgAvDZn8aEnytae+4ou0J0GwFZoHR0hOrTg4qH8GA=
golang.org/x/sys v0.0.0-20210319071255-635bc2c9138d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE=
Expand Down Expand Up @@ -836,8 +844,9 @@ gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUy
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
Expand Down
155 changes: 131 additions & 24 deletions pkg/router/router_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ import (

"k8s.io/klog"

haproxyconfparser "github.com/haproxytech/config-parser/v4"
haproxyconfparseroptions "github.com/haproxytech/config-parser/v4/options"
haproxyconfparsertypes "github.com/haproxytech/config-parser/v4/types"
routercmd "github.com/openshift/router/pkg/cmd/infra/router"
"github.com/openshift/router/pkg/router"
"github.com/openshift/router/pkg/router/controller"
Expand Down Expand Up @@ -213,7 +216,12 @@ func TestConfigTemplate(t *testing.T) {
},
tlsTermination: routev1.TLSTerminationEdge,
},
configSnippet: "acl whitelist src -f " + filepath.Join(h.dirs["whitelist"], h.namespace+":a.txt"),
mustMatchConfig: mustMatchConfig{
section: "backend",
sectionName: edgeBackendName(h.namespace, "a"),
attribute: "acl",
value: "whitelist src -f " + filepath.Join(h.dirs["whitelist"], h.namespace+":a.txt"),
},
},
},
"Whitelist of mixed IPs": {
Expand All @@ -228,7 +236,12 @@ func TestConfigTemplate(t *testing.T) {
},
tlsTermination: routev1.TLSTerminationEdge,
},
configSnippet: "acl whitelist src 192.168.1.0 2001:0db8:85a3:0000:0000:8a2e:0370:7334 172.16.14.10/24 2001:0db8:85a3::8a2e:370:10/64 64:ff9b::192.168.0.1 2600:14a0::/40",
mustMatchConfig: mustMatchConfig{
section: "backend",
sectionName: edgeBackendName(h.namespace, "a1"),
attribute: "acl",
value: "whitelist src 192.168.1.0 2001:0db8:85a3:0000:0000:8a2e:0370:7334 172.16.14.10/24 2001:0db8:85a3::8a2e:370:10/64 64:ff9b::192.168.0.1 2600:14a0::/40",
},
},
},
"Simple HSTS header": {
Expand All @@ -243,7 +256,12 @@ func TestConfigTemplate(t *testing.T) {
},
tlsTermination: routev1.TLSTerminationEdge,
},
configSnippet: `http-response set-header Strict-Transport-Security 'max-age=99999;includeSubDomains;preload'`,
mustMatchConfig: mustMatchConfig{
section: "backend",
sectionName: edgeBackendName(h.namespace, "b"),
attribute: "http-response",
value: `set-header Strict-Transport-Security 'max-age=99999;includeSubDomains;preload'`,
},
},
},
"Simple HSTS header 2": {
Expand All @@ -258,7 +276,12 @@ func TestConfigTemplate(t *testing.T) {
},
tlsTermination: routev1.TLSTerminationEdge,
},
configSnippet: `http-response set-header Strict-Transport-Security 'max-age=99999;includeSubDomains'`,
mustMatchConfig: mustMatchConfig{
section: "backend",
sectionName: edgeBackendName(h.namespace, "b2"),
attribute: "http-response",
value: `set-header Strict-Transport-Security 'max-age=99999;includeSubDomains'`,
},
},
},
"Case insensitive, with white spaces HSTS header": {
Expand All @@ -273,7 +296,12 @@ func TestConfigTemplate(t *testing.T) {
},
tlsTermination: routev1.TLSTerminationEdge,
},
configSnippet: `http-response set-header Strict-Transport-Security 'max-age=99999 ; includesubdomains; PREload'`,
mustMatchConfig: mustMatchConfig{
section: "backend",
sectionName: edgeBackendName(h.namespace, "c"),
attribute: "http-response",
value: `set-header Strict-Transport-Security 'max-age=99999 ; includesubdomains; PREload'`,
},
},
},
"Quotes in HSTS header": {
Expand All @@ -288,7 +316,12 @@ func TestConfigTemplate(t *testing.T) {
},
tlsTermination: routev1.TLSTerminationEdge,
},
configSnippet: `http-response set-header Strict-Transport-Security 'max-age="99999"'`,
mustMatchConfig: mustMatchConfig{
section: "backend",
sectionName: edgeBackendName(h.namespace, "d"),
attribute: "http-response",
value: `set-header Strict-Transport-Security 'max-age="99999"'`,
},
},
},
"Equal sign with LWS in HSTS header": {
Expand All @@ -303,7 +336,12 @@ func TestConfigTemplate(t *testing.T) {
},
tlsTermination: routev1.TLSTerminationEdge,
},
configSnippet: `http-response set-header Strict-Transport-Security 'max-age = "99999"'`,
mustMatchConfig: mustMatchConfig{
section: "backend",
sectionName: edgeBackendName(h.namespace, "f"),
attribute: "http-response",
value: `set-header Strict-Transport-Security 'max-age = "99999"'`,
},
},
},
"Required directive missing": {
Expand All @@ -318,8 +356,13 @@ func TestConfigTemplate(t *testing.T) {
},
tlsTermination: routev1.TLSTerminationEdge,
},
configSnippet: `http-response set-header Strict-Transport-Security 'min-age=99999'`,
notFound: true,
mustMatchConfig: mustMatchConfig{
section: "backend",
sectionName: edgeBackendName(h.namespace, "g"),
attribute: "http-response",
value: `set-header Strict-Transport-Security`,
notFound: true,
},
},
},
// test cases to be revised once HSTS pattern is fully compliant to RFC6797#section-6.1
Expand All @@ -335,8 +378,13 @@ func TestConfigTemplate(t *testing.T) {
},
tlsTermination: routev1.TLSTerminationEdge,
},
configSnippet: `http-response set-header Strict-Transport-Security 'max-age=99999;includesubdomains;preload;wrongdirective'`,
notFound: true,
mustMatchConfig: mustMatchConfig{
section: "backend",
sectionName: edgeBackendName(h.namespace, "h"),
attribute: "http-response",
value: `set-header Strict-Transport-Security 'max-age=99999;includesubdomains;preload;wrongdirective'`,
notFound: true,
},
},
},
"Typo in HSTS header directive": {
Expand All @@ -351,8 +399,13 @@ func TestConfigTemplate(t *testing.T) {
},
tlsTermination: routev1.TLSTerminationEdge,
},
configSnippet: `http-response set-header Strict-Transport-Security 'max-age=99999;includesubdomain'`,
notFound: true,
mustMatchConfig: mustMatchConfig{
section: "backend",
sectionName: edgeBackendName(h.namespace, "i"),
attribute: "http-response",
value: `set-header Strict-Transport-Security 'max-age=99999;includesubdomain'`,
notFound: true,
},
},
},
}
Expand Down Expand Up @@ -383,21 +436,16 @@ func TestConfigTemplate(t *testing.T) {

// check the generated config
config := filepath.Join(h.workdir, "conf", "haproxy.config")
contents, err := ioutil.ReadFile(config)
parser, err := haproxyconfparser.New(haproxyconfparseroptions.Path(config))
if err != nil {
t.Fatalf("Failed to read the generated config: %v", err)
t.Fatalf("Failed to parse the generated config: %v", err)
}

for name, expectations := range tests {
for _, expectation := range expectations {
t.Run(name, func(t *testing.T) {
contains := strings.Contains(string(contents), expectation.configSnippet)
if !contains && !expectation.notFound {
t.Fatalf("Snippet expected but not found: [%s]", expectation.configSnippet)
}

if contains && expectation.notFound {
t.Fatalf("Snippet unexpected but found: [%s]", expectation.configSnippet)
if err := expectation.Match(parser); err != nil {
t.Fatalf(err.Error())
}
})
}
Expand Down Expand Up @@ -453,8 +501,62 @@ func (e mustCreate) Apply(h *harness) error {

type mustCreateWithConfig struct {
mustCreate
configSnippet string
notFound bool
mustMatchConfig
}

// mustMatchConfig uses HAProxy's config parser to find config snippets
type mustMatchConfig struct {
section string
sectionName string
attribute string
value string
notFound bool
}

func (m mustMatchConfig) Match(parser haproxyconfparser.Parser) error {
data, err := parser.Get(haproxyconfparser.Section(m.section), m.sectionName, m.attribute)
if err != nil {
if m.notFound {
return nil
}
return fmt.Errorf("unable to find requested config attribute: [%s], error: %v", m, err)
}

contains := false
switch data := data.(type) {
case []haproxyconfparsertypes.HTTPAction:
for _, a := range data {
if a.String() == m.value {
contains = true
break
}
}
case []haproxyconfparsertypes.ACL:
for _, a := range data {
if a.Name+" "+a.Criterion+" "+a.Value == m.value {
contains = true
break
}
}
}

if !contains && !m.notFound {
return fmt.Errorf("config from section %s is expected but not found: [%s]", m.Section(), m)
}

if contains && m.notFound {
return fmt.Errorf("config from section %s is unexpected but found: [%s]", m.Section(), m)
}

return nil
}

func (m mustMatchConfig) Section() string {
return m.section + " " + m.sectionName
}

func (m mustMatchConfig) String() string {
return m.attribute + " " + m.value
}

type mustDelete []string
Expand Down Expand Up @@ -551,3 +653,8 @@ func createRouterDirs() {
os.MkdirAll(d, 0775)
}
}

// edgeBackendName contructs the HAProxy config's backend name for an edge route
func edgeBackendName(ns, route string) string {
return "be_edge_http:" + ns + ":" + route
}
24 changes: 24 additions & 0 deletions vendor/github.com/gofrs/flock/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions vendor/github.com/gofrs/flock/.travis.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 27 additions & 0 deletions vendor/github.com/gofrs/flock/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 6316ee7

Please sign in to comment.