Skip to content

Commit

Permalink
Update Ingress and dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
jcmoraisjr committed Nov 19, 2017
1 parent 618426e commit 011df80
Show file tree
Hide file tree
Showing 48 changed files with 4,384 additions and 120 deletions.
16 changes: 15 additions & 1 deletion Godeps/Godeps.json

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

8 changes: 0 additions & 8 deletions pkg/common/ingress/annotations/authreq/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ const (
authURL = "ingress.kubernetes.io/auth-url"
authSigninURL = "ingress.kubernetes.io/auth-signin"
authMethod = "ingress.kubernetes.io/auth-method"
authBody = "ingress.kubernetes.io/auth-send-body"
authHeaders = "ingress.kubernetes.io/auth-response-headers"
)

Expand All @@ -43,7 +42,6 @@ type External struct {
Host string `json:"host"`
SigninURL string `json:"signinUrl"`
Method string `json:"method"`
SendBody bool `json:"sendBody"`
ResponseHeaders []string `json:"responseHeaders,omitEmpty"`
}

Expand All @@ -67,9 +65,6 @@ func (e1 *External) Equal(e2 *External) bool {
if e1.Method != e2.Method {
return false
}
if e1.SendBody != e2.SendBody {
return false
}
if e1.Method != e2.Method {
return false
}
Expand Down Expand Up @@ -170,14 +165,11 @@ func (a authReq) Parse(ing *extensions.Ingress) (interface{}, error) {
}
}

sb, _ := parser.GetBoolAnnotation(authBody, ing)

return &External{
URL: str,
Host: ur.Hostname(),
SigninURL: signin,
Method: m,
SendBody: sb,
ResponseHeaders: h,
}, nil
}
17 changes: 17 additions & 0 deletions pkg/common/ingress/annotations/authtls/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,28 @@ import (
ing_errors "github.com/jcmoraisjr/haproxy-ingress/pkg/common/ingress/errors"
"github.com/jcmoraisjr/haproxy-ingress/pkg/common/ingress/resolver"
"github.com/jcmoraisjr/haproxy-ingress/pkg/common/k8s"
"regexp"
)

const (
// name of the secret
annotationAuthTLSSecret = "ingress.kubernetes.io/auth-tls-secret"
annotationAuthVerifyClient = "ingress.kubernetes.io/auth-tls-verify-client"
annotationAuthTLSDepth = "ingress.kubernetes.io/auth-tls-verify-depth"
annotationAuthTLSErrorPage = "ingress.kubernetes.io/auth-tls-error-page"
defaultAuthTLSDepth = 1
defaultAuthVerifyClient = "on"
)

var (
authVerifyClientRegex = regexp.MustCompile(`on|off|optional|optional_no_ca`)
)

// AuthSSLConfig contains the AuthSSLCert used for muthual autentication
// and the configured ValidationDepth
type AuthSSLConfig struct {
resolver.AuthSSLCert
VerifyClient string `json:"verify_client"`
ValidationDepth int `json:"validationDepth"`
ErrorPage string `json:"errorPage"`
}
Expand All @@ -53,6 +61,9 @@ func (assl1 *AuthSSLConfig) Equal(assl2 *AuthSSLConfig) bool {
if !(&assl1.AuthSSLCert).Equal(&assl2.AuthSSLCert) {
return false
}
if assl1.VerifyClient != assl2.VerifyClient {
return false
}
if assl1.ValidationDepth != assl2.ValidationDepth {
return false
}
Expand Down Expand Up @@ -89,6 +100,11 @@ func (a authTLS) Parse(ing *extensions.Ingress) (interface{}, error) {
return &AuthSSLConfig{}, ing_errors.NewLocationDenied(err.Error())
}

tlsVerifyClient, err := parser.GetStringAnnotation(annotationAuthVerifyClient, ing)
if err != nil || !authVerifyClientRegex.MatchString(tlsVerifyClient) {
tlsVerifyClient = defaultAuthVerifyClient
}

tlsdepth, err := parser.GetIntAnnotation(annotationAuthTLSDepth, ing)
if err != nil || tlsdepth == 0 {
tlsdepth = defaultAuthTLSDepth
Expand All @@ -108,6 +124,7 @@ func (a authTLS) Parse(ing *extensions.Ingress) (interface{}, error) {

return &AuthSSLConfig{
AuthSSLCert: *authCert,
VerifyClient: tlsVerifyClient,
ValidationDepth: tlsdepth,
ErrorPage: errorpage,
}, nil
Expand Down
94 changes: 92 additions & 2 deletions pkg/common/ingress/annotations/cors/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,115 @@ limitations under the License.
package cors

import (
"regexp"

extensions "k8s.io/api/extensions/v1beta1"

"github.com/jcmoraisjr/haproxy-ingress/pkg/common/ingress/annotations/parser"
)

const (
annotation = "ingress.kubernetes.io/enable-cors"
annotationCorsEnabled = "ingress.kubernetes.io/enable-cors"
annotationCorsAllowOrigin = "ingress.kubernetes.io/cors-allow-origin"
annotationCorsAllowMethods = "ingress.kubernetes.io/cors-allow-methods"
annotationCorsAllowHeaders = "ingress.kubernetes.io/cors-allow-headers"
annotationCorsAllowCredentials = "ingress.kubernetes.io/cors-allow-credentials"
// Default values
defaultCorsMethods = "GET, PUT, POST, DELETE, PATCH, OPTIONS"
defaultCorsHeaders = "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization"
)

var (
// Regex are defined here to prevent information leak, if user tries to set anything not valid
// that could cause the Response to contain some internal value/variable (like returning $pid, $upstream_addr, etc)
// Origin must contain a http/s Origin (including or not the port) or the value '*'
corsOriginRegex = regexp.MustCompile(`^(https?://[A-Za-z0-9\-\.]*(:[0-9]+)?|\*)?$`)
// Method must contain valid methods list (PUT, GET, POST, BLA)
// May contain or not spaces between each verb
corsMethodsRegex = regexp.MustCompile(`^([A-Za-z]+,?\s?)+$`)
// Headers must contain valid values only (X-HEADER12, X-ABC)
// May contain or not spaces between each Header
corsHeadersRegex = regexp.MustCompile(`^([A-Za-z0-9\-\_]+,?\s?)+$`)
)

type cors struct {
}

// CorsConfig contains the Cors configuration to be used in the Ingress
type CorsConfig struct {
CorsEnabled bool `json:"corsEnabled"`
CorsAllowOrigin string `json:"corsAllowOrigin"`
CorsAllowMethods string `json:"corsAllowMethods"`
CorsAllowHeaders string `json:"corsAllowHeaders"`
CorsAllowCredentials bool `json:"corsAllowCredentials"`
}

// NewParser creates a new CORS annotation parser
func NewParser() parser.IngressAnnotation {
return cors{}
}

// Equal tests for equality between two External types
func (c1 *CorsConfig) Equal(c2 *CorsConfig) bool {
if c1 == c2 {
return true
}
if c1 == nil || c2 == nil {
return false
}
if c1.CorsAllowCredentials != c2.CorsAllowCredentials {
return false
}
if c1.CorsAllowHeaders != c2.CorsAllowHeaders {
return false
}
if c1.CorsAllowMethods != c2.CorsAllowMethods {
return false
}
if c1.CorsAllowOrigin != c2.CorsAllowOrigin {
return false
}
if c1.CorsEnabled != c2.CorsEnabled {
return false
}

return true
}

// Parse parses the annotations contained in the ingress
// rule used to indicate if the location/s should allows CORS
func (a cors) Parse(ing *extensions.Ingress) (interface{}, error) {
return parser.GetBoolAnnotation(annotation, ing)
corsenabled, err := parser.GetBoolAnnotation(annotationCorsEnabled, ing)
if err != nil {
corsenabled = false
}

corsalloworigin, err := parser.GetStringAnnotation(annotationCorsAllowOrigin, ing)
if err != nil || corsalloworigin == "" || !corsOriginRegex.MatchString(corsalloworigin) {
corsalloworigin = "*"
}

corsallowheaders, err := parser.GetStringAnnotation(annotationCorsAllowHeaders, ing)
if err != nil || corsallowheaders == "" || !corsHeadersRegex.MatchString(corsallowheaders) {
corsallowheaders = defaultCorsHeaders
}

corsallowmethods, err := parser.GetStringAnnotation(annotationCorsAllowMethods, ing)
if err != nil || corsallowmethods == "" || !corsMethodsRegex.MatchString(corsallowmethods) {
corsallowmethods = defaultCorsMethods
}

corsallowcredentials, err := parser.GetBoolAnnotation(annotationCorsAllowCredentials, ing)
if err != nil {
corsallowcredentials = true
}

return &CorsConfig{
CorsEnabled: corsenabled,
CorsAllowOrigin: corsalloworigin,
CorsAllowHeaders: corsallowheaders,
CorsAllowMethods: corsallowmethods,
CorsAllowCredentials: corsallowcredentials,
}, nil

}
2 changes: 1 addition & 1 deletion pkg/common/ingress/annotations/ipwhitelist/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ import (

"github.com/pkg/errors"

extensions "k8s.io/api/extensions/v1beta1"
"github.com/jcmoraisjr/haproxy-ingress/pkg/common/net"
extensions "k8s.io/api/extensions/v1beta1"

"github.com/jcmoraisjr/haproxy-ingress/pkg/common/ingress/annotations/parser"
ing_errors "github.com/jcmoraisjr/haproxy-ingress/pkg/common/ingress/errors"
Expand Down
2 changes: 1 addition & 1 deletion pkg/common/ingress/annotations/serviceupstream/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ limitations under the License.
package serviceupstream

import (
extensions "k8s.io/api/extensions/v1beta1"
"github.com/jcmoraisjr/haproxy-ingress/pkg/common/ingress/annotations/parser"
extensions "k8s.io/api/extensions/v1beta1"
)

const (
Expand Down
42 changes: 42 additions & 0 deletions pkg/common/ingress/annotations/upstreamhashby/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package upstreamhashby

import (
extensions "k8s.io/api/extensions/v1beta1"

"github.com/jcmoraisjr/haproxy-ingress/pkg/common/ingress/annotations/parser"
)

const (
annotation = "ingress.kubernetes.io/upstream-hash-by"
)

type upstreamhashby struct {
}

// NewParser creates a new CORS annotation parser
func NewParser() parser.IngressAnnotation {
return upstreamhashby{}
}

// Parse parses the annotations contained in the ingress rule
// used to indicate if the location/s contains a fragment of
// configuration to be included inside the paths of the rules
func (a upstreamhashby) Parse(ing *extensions.Ingress) (interface{}, error) {
return parser.GetStringAnnotation(annotation, ing)
}
18 changes: 16 additions & 2 deletions pkg/common/ingress/controller/annotations.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package controller
import (
"github.com/golang/glog"

extensions "k8s.io/api/extensions/v1beta1"
"github.com/jcmoraisjr/haproxy-ingress/pkg/common/ingress/annotations/alias"
"github.com/jcmoraisjr/haproxy-ingress/pkg/common/ingress/annotations/auth"
"github.com/jcmoraisjr/haproxy-ingress/pkg/common/ingress/annotations/authreq"
Expand All @@ -41,10 +40,12 @@ import (
"github.com/jcmoraisjr/haproxy-ingress/pkg/common/ingress/annotations/sessionaffinity"
"github.com/jcmoraisjr/haproxy-ingress/pkg/common/ingress/annotations/snippet"
"github.com/jcmoraisjr/haproxy-ingress/pkg/common/ingress/annotations/sslpassthrough"
"github.com/jcmoraisjr/haproxy-ingress/pkg/common/ingress/annotations/upstreamhashby"
"github.com/jcmoraisjr/haproxy-ingress/pkg/common/ingress/annotations/upstreamvhost"
"github.com/jcmoraisjr/haproxy-ingress/pkg/common/ingress/annotations/vtsfilterkey"
"github.com/jcmoraisjr/haproxy-ingress/pkg/common/ingress/errors"
"github.com/jcmoraisjr/haproxy-ingress/pkg/common/ingress/resolver"
extensions "k8s.io/api/extensions/v1beta1"
)

type extractorConfig interface {
Expand All @@ -66,7 +67,7 @@ func newAnnotationExtractor(cfg extractorConfig) annotationExtractor {
"BasicDigestAuth": auth.NewParser(auth.AuthDirectory, cfg),
"ExternalAuth": authreq.NewParser(),
"CertificateAuth": authtls.NewParser(cfg),
"EnableCORS": cors.NewParser(),
"CorsConfig": cors.NewParser(),
"HealthCheck": healthcheck.NewParser(cfg),
"Whitelist": ipwhitelist.NewParser(cfg),
"UsePortInRedirects": portinredirect.NewParser(cfg),
Expand All @@ -82,6 +83,7 @@ func newAnnotationExtractor(cfg extractorConfig) annotationExtractor {
"Alias": alias.NewParser(),
"ClientBodyBufferSize": clientbodybuffersize.NewParser(),
"DefaultBackend": defaultbackend.NewParser(cfg),
"UpstreamHashBy": upstreamhashby.NewParser(),
"UpstreamVhost": upstreamvhost.NewParser(),
"VtsFilterKey": vtsfilterkey.NewParser(),
"ServerSnippet": serversnippet.NewParser(),
Expand Down Expand Up @@ -128,9 +130,11 @@ const (
sessionAffinity = "SessionAffinity"
serviceUpstream = "ServiceUpstream"
serverAlias = "Alias"
corsConfig = "CorsConfig"
clientBodyBufferSize = "ClientBodyBufferSize"
certificateAuth = "CertificateAuth"
serverSnippet = "ServerSnippet"
upstreamHashBy = "UpstreamHashBy"
)

func (e *annotationExtractor) ServiceUpstream(ing *extensions.Ingress) bool {
Expand Down Expand Up @@ -172,6 +176,11 @@ func (e *annotationExtractor) SessionAffinity(ing *extensions.Ingress) *sessiona
return val.(*sessionaffinity.AffinityConfig)
}

func (e *annotationExtractor) Cors(ing *extensions.Ingress) *cors.CorsConfig {
val, _ := e.annotations[corsConfig].Parse(ing)
return val.(*cors.CorsConfig)
}

func (e *annotationExtractor) CertificateAuth(ing *extensions.Ingress) *authtls.AuthSSLConfig {
val, err := e.annotations[certificateAuth].Parse(ing)
if errors.IsMissingAnnotations(err) {
Expand All @@ -189,3 +198,8 @@ func (e *annotationExtractor) ServerSnippet(ing *extensions.Ingress) string {
val, _ := e.annotations[serverSnippet].Parse(ing)
return val.(string)
}

func (e *annotationExtractor) UpstreamHashBy(ing *extensions.Ingress) string {
val, _ := e.annotations[upstreamHashBy].Parse(ing)
return val.(string)
}
Loading

0 comments on commit 011df80

Please sign in to comment.