Add support for custom proxy headers using a ConfigMap #246

Merged
merged 3 commits into from Feb 16, 2017
Jump to file or symbol
Failed to load files and symbols.
+54 −2
Split
Next

Add support for custom proxy headers using a ConfigMap

  • Loading branch information...
commit 5cc5669938108ab7429bc7eee40c18a6ba18150a @aledbf aledbf committed Feb 7, 2017
@@ -101,6 +101,8 @@ type NGINXController struct {
configmap *api.ConfigMap
+ storeLister ingress.StoreLister
+
binary string
}
@@ -276,11 +278,16 @@ Error: %v
return nil
}
-// SetConfig ...
+// SetConfig sets the configured configmap
func (n *NGINXController) SetConfig(cmap *api.ConfigMap) {
n.configmap = cmap
}
+// SetListers sets the configured store listers in the generic ingress controller
+func (n *NGINXController) SetListers(lister ingress.StoreLister) {
+ n.storeLister = lister
+}
+
// OnUpdate is called by syncQueue in https://github.com/aledbf/ingress-controller/blob/master/pkg/ingress/controller/controller.go#L82
// periodically to keep the configuration in sync.
//
@@ -324,7 +331,20 @@ func (n *NGINXController) OnUpdate(ingressCfg ingress.Configuration) ([]byte, er
// and we leave some room to avoid consuming all the FDs available
maxOpenFiles := (sysctlFSFileMax() / cfg.WorkerProcesses) - 1024
+ setHeaders := map[string]string{}
+ if cfg.ProxySetHeaders != "" {
+ cmap, exists, err := n.storeLister.ConfigMap.GetByKey(cfg.ProxySetHeaders)
+ if err != nil {
+ glog.Warningf("unexpected error reading configmap %v: %v", cfg.ProxySetHeaders, err)
+ }
+
+ if exists {
+ setHeaders = cmap.(*api.ConfigMap).Data
+ }
+ }
+
return n.t.Write(config.TemplateConfig{
+ ProxySetHeaders: setHeaders,
MaxOpenFiles: maxOpenFiles,
BacklogSize: sysctlSomaxconn(),
Backends: ingressCfg.Backends,
@@ -152,6 +152,9 @@ type Configuration struct {
// of your external load balancer
ProxyRealIPCIDR string `json:"proxy-real-ip-cidr,omitempty"`
+ // Sets the name of the configmap that contains the headers to pass to the backend
+ ProxySetHeaders string `json:"proxy-set-headers,omitempty"`
+
// Maximum size of the server names hash tables used in server names, map directive’s values,
// MIME types, names of request header strings, etcd.
// http://nginx.org/en/docs/hash.html
@@ -283,6 +286,7 @@ func NewDefault() Configuration {
// TemplateConfig contains the nginx configuration to render the file nginx.conf
type TemplateConfig struct {
+ ProxySetHeaders map[string]string
MaxOpenFiles int
BacklogSize int
Backends []*ingress.Backend
@@ -1,4 +1,4 @@
-{{ $cfg := .Cfg }}{{ $healthzURI := .HealthzURI }}{{ $backends := .Backends }}
+{{ $cfg := .Cfg }}{{ $healthzURI := .HealthzURI }}{{ $backends := .Backends }}{{ $proxyHeaders := .ProxySetHeaders }}
daemon off;
worker_processes {{ $cfg.WorkerProcesses }};
@@ -307,6 +307,11 @@ http {
# https://www.nginx.com/blog/mitigating-the-httpoxy-vulnerability-with-nginx/
proxy_set_header Proxy "";
+ # Custom headers
+ {{ range $k, $v := $proxyHeaders }}
+ proxy_set_header {{ $k }} "{{ $v }}";
+ {{ end }}
+
proxy_connect_timeout {{ $location.Proxy.ConnectTimeout }}s;
proxy_send_timeout {{ $location.Proxy.SendTimeout }}s;
proxy_read_timeout {{ $location.Proxy.ReadTimeout }}s;
@@ -304,6 +304,14 @@ func newIngressController(config *Configuration) *GenericController {
ic.annotations = newAnnotationExtractor(ic)
+ ic.cfg.Backend.SetListers(ingress.StoreLister{
+ Ingress: ic.ingLister,
+ Service: ic.svcLister,
+ Endpoint: ic.endpLister,
+ Secret: ic.secrLister,
+ ConfigMap: ic.mapLister,
+ })
+
return &ic
}
@@ -18,8 +18,10 @@ package ingress
import (
"k8s.io/kubernetes/pkg/api"
+ "k8s.io/kubernetes/pkg/client/cache"
"k8s.io/kubernetes/pkg/healthz"
+ cache_store "k8s.io/ingress/core/pkg/cache"
"k8s.io/ingress/core/pkg/ingress/annotations/auth"
"k8s.io/ingress/core/pkg/ingress/annotations/authreq"
"k8s.io/ingress/core/pkg/ingress/annotations/ipwhitelist"
@@ -81,13 +83,26 @@ type Controller interface {
OnUpdate(Configuration) ([]byte, error)
// ConfigMap content of --configmap
SetConfig(*api.ConfigMap)
+ // SetListers allows the access of store listers present in the generic controller
+ // This avoid the use of the kubernetes client.
+ SetListers(StoreLister)
// BackendDefaults returns the minimum settings required to configure the
// communication to endpoints
BackendDefaults() defaults.Backend
// Info returns information about the ingress controller
Info() *BackendInfo
}
+// StoreLister returns the configured stores for ingresses, services,
+// endpoints, secrets and configmaps.
+type StoreLister struct {
+ Ingress cache_store.StoreToIngressLister
+ Service cache.StoreToServiceLister
+ Endpoint cache.StoreToEndpointsLister
+ Secret cache_store.StoreToSecretsLister
+ ConfigMap cache_store.StoreToConfigmapLister
+}
+
// BackendInfo returns information about the backend.
// This fields contains information that helps to track issues or to
// map the running ingress controller to source code