Add annotation to add CORS support

This commit is contained in:
Manuel de Brito Fontes 2016-09-22 15:00:09 -03:00
parent b49a91965c
commit e74b8039a5
4 changed files with 98 additions and 1 deletions

View file

@ -43,6 +43,7 @@ import (
"k8s.io/contrib/ingress/controllers/nginx/nginx" "k8s.io/contrib/ingress/controllers/nginx/nginx"
"k8s.io/contrib/ingress/controllers/nginx/nginx/auth" "k8s.io/contrib/ingress/controllers/nginx/nginx/auth"
"k8s.io/contrib/ingress/controllers/nginx/nginx/config" "k8s.io/contrib/ingress/controllers/nginx/nginx/config"
"k8s.io/contrib/ingress/controllers/nginx/nginx/cors"
"k8s.io/contrib/ingress/controllers/nginx/nginx/healthcheck" "k8s.io/contrib/ingress/controllers/nginx/nginx/healthcheck"
"k8s.io/contrib/ingress/controllers/nginx/nginx/ingress" "k8s.io/contrib/ingress/controllers/nginx/nginx/ingress"
"k8s.io/contrib/ingress/controllers/nginx/nginx/ipwhitelist" "k8s.io/contrib/ingress/controllers/nginx/nginx/ipwhitelist"
@ -717,6 +718,11 @@ func (lbc *loadBalancerController) getUpstreamServers(ngxCfg config.Configuratio
glog.V(3).Infof("error reading white list annotation in Ingress %v/%v: %v", ing.GetNamespace(), ing.GetName(), err) glog.V(3).Infof("error reading white list annotation in Ingress %v/%v: %v", ing.GetNamespace(), ing.GetName(), err)
} }
eCORS, err := cors.ParseAnnotations(ing)
if err != nil {
glog.V(3).Infof("error reading CORS annotation in Ingress %v/%v: %v", ing.GetNamespace(), ing.GetName(), err)
}
host := rule.Host host := rule.Host
if host == "" { if host == "" {
host = defServerName host = defServerName
@ -749,6 +755,7 @@ func (lbc *loadBalancerController) getUpstreamServers(ngxCfg config.Configuratio
loc.Redirect = *locRew loc.Redirect = *locRew
loc.SecureUpstream = secUpstream loc.SecureUpstream = secUpstream
loc.Whitelist = *wl loc.Whitelist = *wl
loc.EnableCORS = eCORS
addLoc = false addLoc = false
continue continue
@ -763,7 +770,6 @@ func (lbc *loadBalancerController) getUpstreamServers(ngxCfg config.Configuratio
} }
if addLoc { if addLoc {
server.Locations = append(server.Locations, &ingress.Location{ server.Locations = append(server.Locations, &ingress.Location{
Path: nginxPath, Path: nginxPath,
Upstream: *ups, Upstream: *ups,
@ -772,6 +778,7 @@ func (lbc *loadBalancerController) getUpstreamServers(ngxCfg config.Configuratio
Redirect: *locRew, Redirect: *locRew,
SecureUpstream: secUpstream, SecureUpstream: secUpstream,
Whitelist: *wl, Whitelist: *wl,
EnableCORS: eCORS,
}) })
} }
} }

View file

@ -228,6 +228,10 @@ http {
proxy_set_header Authorization ""; proxy_set_header Authorization "";
{{- end }} {{- end }}
{{ if $location.EnableCORS }}
{{ template "CORS" }}
{{ end }}
proxy_set_header Host $host; proxy_set_header Host $host;
# Pass Real IP # Pass Real IP
@ -374,3 +378,38 @@ stream {
} }
{{ end }} {{ end }}
{{ end }} {{ end }}
{{/* CORS support from https://michielkalkman.com/snippets/nginx-cors-open-configuration.html */}}
{{ define "CORS" }}
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
#
# Om nom nom cookies
#
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
#
# Custom headers and headers various browsers *should* be OK with but aren't
#
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
#
# Tell client that this pre-flight info is valid for 20 days
#
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
{{ end }}

View file

@ -0,0 +1,50 @@
/*
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 cors
import (
"errors"
"strconv"
"k8s.io/kubernetes/pkg/apis/extensions"
)
const (
cors = "ingress.kubernetes.io/enable-cors"
)
type ingAnnotations map[string]string
func (a ingAnnotations) cors() bool {
val, ok := a[cors]
if ok {
if b, err := strconv.ParseBool(val); err == nil {
return b
}
}
return false
}
// ParseAnnotations parses the annotations contained in the ingress
// rule used to indicate if the location/s should allows CORS
func ParseAnnotations(ing *extensions.Ingress) (bool, error) {
if ing.GetAnnotations() == nil {
return false, errors.New("no annotations present")
}
return ingAnnotations(ing.GetAnnotations()).cors(), nil
}

View file

@ -101,6 +101,7 @@ type Location struct {
Redirect rewrite.Redirect Redirect rewrite.Redirect
SecureUpstream bool SecureUpstream bool
Whitelist ipwhitelist.SourceRange Whitelist ipwhitelist.SourceRange
EnableCORS bool
} }
// LocationByPath sorts location by path // LocationByPath sorts location by path