From ed9a416b01a4dc7635b28bca163f3b83e4a6c71d Mon Sep 17 00:00:00 2001 From: Manuel de Brito Fontes Date: Thu, 10 Nov 2016 19:56:29 -0300 Subject: [PATCH 1/5] Split implementations from generic code --- controllers/gce/backends/backends_test.go | 2 +- controllers/nginx/.gitignore | 3 +- controllers/nginx/Changelog.md | 28 + controllers/nginx/Makefile | 51 +- controllers/nginx/README.md | 62 +- controllers/nginx/controller.go | 1244 ----------------- .../lua-resty-http-0.07-0.rockspec | 33 - controllers/nginx/main.go | 192 --- controllers/nginx/nginx/command.go | 138 -- controllers/nginx/nginx/ingress/nginx.go | 130 -- controllers/nginx/nginx/main.go | 118 -- controllers/nginx/nginx/ssl.go | 135 -- controllers/nginx/nginx/utils.go | 224 --- controllers/nginx/nginx/utils_test.go | 101 -- controllers/nginx/pkg/cmd/controller/main.go | 60 + controllers/nginx/pkg/cmd/controller/nginx.go | 266 ++++ controllers/nginx/pkg/cmd/controller/utils.go | 62 + .../nginx/pkg/cmd/controller/utils_test.go | 41 + .../nginx/{nginx => pkg}/config/config.go | 100 +- controllers/nginx/pkg/template/configmap.go | 122 ++ .../nginx/pkg/template/configmap_test.go | 83 ++ .../nginx/{nginx => pkg}/template/template.go | 196 +-- .../{nginx => pkg}/template/template_test.go | 4 +- controllers/nginx/pkg/version/version.go | 26 + controllers/nginx/{ => rootfs}/Dockerfile | 11 +- .../{ => rootfs/etc/nginx}/lua/error_page.lua | 0 .../nginx/{ => rootfs/etc/nginx}/lua/trie.lua | 0 .../lua/vendor/lua-resty-http/.gitignore | 0 .../nginx}/lua/vendor/lua-resty-http/LICENSE | 0 .../nginx}/lua/vendor/lua-resty-http/Makefile | 0 .../lua/vendor/lua-resty-http/README.md | 23 +- .../vendor/lua-resty-http/lib/resty/http.lua | 60 +- .../lua-resty-http/lib/resty/http_headers.lua | 0 .../lua-resty-http-0.09-0.rockspec | 22 + .../lua/vendor/lua-resty-http/t/01-basic.t | 4 +- .../lua/vendor/lua-resty-http/t/02-chunked.t | 0 .../vendor/lua-resty-http/t/03-requestbody.t | 0 .../lua/vendor/lua-resty-http/t/04-trailers.t | 0 .../lua/vendor/lua-resty-http/t/05-stream.t | 0 .../lua-resty-http/t/06-simpleinterface.t | 0 .../vendor/lua-resty-http/t/07-keepalive.t | 58 + .../lua/vendor/lua-resty-http/t/08-pipeline.t | 0 .../lua/vendor/lua-resty-http/t/09-ssl.t | 0 .../lua-resty-http/t/10-clientbodyreader.t | 0 .../lua/vendor/lua-resty-http/t/11-proxy.t | 0 .../t/12-case_insensitive_headers.t | 0 .../vendor/lua-resty-http/t/13-default-path.t | 0 .../vendor/lua-resty-http/t/14-host-header.t | 161 +++ .../lua/vendor/lua-resty-http/t/cert/test.crt | 24 + .../lua/vendor/lua-resty-http/t/cert/test.key | 27 + .../lua/vendor/lua-resty-http/util/lua-releng | 0 .../etc/nginx/nginx.conf} | 0 .../etc/nginx/template}/nginx.tmpl | 209 +-- .../ingress-controller/clean-nginx-conf.sh | 8 + controllers/nginx/utils.go | 301 ---- core/pkg/cache/main.go | 34 + .../pkg/ingress/annotations}/auth/main.go | 80 +- .../ingress/annotations}/auth/main_test.go | 85 +- .../pkg/ingress/annotations}/authreq/main.go | 71 +- .../ingress/annotations}/authreq/main_test.go | 5 - core/pkg/ingress/annotations/authtls/main.go | 65 + .../ingress/annotations/authtls/main_test.go | 107 ++ .../pkg/ingress/annotations}/cors/main.go | 21 +- .../ingress/annotations}/healthcheck/main.go | 55 +- .../annotations}/healthcheck/main_test.go | 40 +- .../ingress/annotations}/ipwhitelist/main.go | 47 +- .../annotations}/ipwhitelist/main_test.go | 70 +- core/pkg/ingress/annotations/parser/main.go | 102 ++ .../ingress/annotations/parser/main_test.go | 154 ++ core/pkg/ingress/annotations/proxy/main.go | 74 + .../ingress/annotations/proxy/main_test.go | 90 ++ .../ingress/annotations}/ratelimit/main.go | 37 +- .../annotations}/ratelimit/main_test.go | 29 - .../pkg/ingress/annotations}/rewrite/main.go | 61 +- .../ingress/annotations}/rewrite/main_test.go | 37 +- .../annotations}/secureupstream/main.go | 21 +- .../annotations}/secureupstream/main_test.go | 6 +- .../ingress/annotations/service/service.go | 73 + .../annotations/sslpassthrough/main.go | 45 + .../annotations/sslpassthrough/main_test.go | 74 + core/pkg/ingress/controller/backend_ssl.go | 161 +++ core/pkg/ingress/controller/controller.go | 1076 ++++++++++++++ core/pkg/ingress/controller/launch.go | 182 +++ core/pkg/ingress/controller/metrics.go | 60 + core/pkg/ingress/controller/named_port.go | 105 ++ core/pkg/ingress/controller/util.go | 95 ++ core/pkg/ingress/controller/util_test.go | 50 + core/pkg/ingress/defaults/main.go | 60 + core/pkg/ingress/status/election.go | 119 ++ core/pkg/ingress/status/status.go | 283 ++++ core/pkg/ingress/types.go | 214 +++ core/pkg/k8s/main.go | 110 ++ core/pkg/k8s/main_test.go | 116 ++ core/pkg/net/dns/dns.go | 52 + core/pkg/net/dns/dns_test.go | 31 + core/pkg/net/ssl/ssl.go | 179 +++ .../nginx => core/pkg/net/ssl}/ssl_test.go | 17 +- core/pkg/strings/string.go | 27 + core/pkg/task/queue.go | 123 ++ .../pkg/watch}/file_watcher.go | 17 +- core/pkg/watch/file_watcher_test.go | 45 + hack/e2e-internal/e2e-down.sh | 14 + hack/e2e-internal/e2e-env.sh | 21 + hack/e2e-internal/e2e-status.sh | 11 + hack/e2e-internal/e2e-up.sh | 55 + hack/e2e-internal/ginkgo-e2e.sh | 3 + hack/e2e.go | 285 ++++ 107 files changed, 5777 insertions(+), 3546 deletions(-) delete mode 100644 controllers/nginx/controller.go delete mode 100644 controllers/nginx/lua/vendor/lua-resty-http/lua-resty-http-0.07-0.rockspec delete mode 100644 controllers/nginx/main.go delete mode 100644 controllers/nginx/nginx/command.go delete mode 100644 controllers/nginx/nginx/ingress/nginx.go delete mode 100644 controllers/nginx/nginx/main.go delete mode 100644 controllers/nginx/nginx/ssl.go delete mode 100644 controllers/nginx/nginx/utils.go delete mode 100644 controllers/nginx/nginx/utils_test.go create mode 100644 controllers/nginx/pkg/cmd/controller/main.go create mode 100644 controllers/nginx/pkg/cmd/controller/nginx.go create mode 100644 controllers/nginx/pkg/cmd/controller/utils.go create mode 100644 controllers/nginx/pkg/cmd/controller/utils_test.go rename controllers/nginx/{nginx => pkg}/config/config.go (74%) create mode 100644 controllers/nginx/pkg/template/configmap.go create mode 100644 controllers/nginx/pkg/template/configmap_test.go rename controllers/nginx/{nginx => pkg}/template/template.go (61%) rename controllers/nginx/{nginx => pkg}/template/template_test.go (96%) create mode 100644 controllers/nginx/pkg/version/version.go rename controllers/nginx/{ => rootfs}/Dockerfile (78%) rename controllers/nginx/{ => rootfs/etc/nginx}/lua/error_page.lua (100%) rename controllers/nginx/{ => rootfs/etc/nginx}/lua/trie.lua (100%) rename controllers/nginx/{ => rootfs/etc/nginx}/lua/vendor/lua-resty-http/.gitignore (100%) rename controllers/nginx/{ => rootfs/etc/nginx}/lua/vendor/lua-resty-http/LICENSE (100%) rename controllers/nginx/{ => rootfs/etc/nginx}/lua/vendor/lua-resty-http/Makefile (100%) rename controllers/nginx/{ => rootfs/etc/nginx}/lua/vendor/lua-resty-http/README.md (96%) rename controllers/nginx/{ => rootfs/etc/nginx}/lua/vendor/lua-resty-http/lib/resty/http.lua (92%) rename controllers/nginx/{ => rootfs/etc/nginx}/lua/vendor/lua-resty-http/lib/resty/http_headers.lua (100%) create mode 100644 controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/lua-resty-http-0.09-0.rockspec rename controllers/nginx/{ => rootfs/etc/nginx}/lua/vendor/lua-resty-http/t/01-basic.t (98%) rename controllers/nginx/{ => rootfs/etc/nginx}/lua/vendor/lua-resty-http/t/02-chunked.t (100%) rename controllers/nginx/{ => rootfs/etc/nginx}/lua/vendor/lua-resty-http/t/03-requestbody.t (100%) rename controllers/nginx/{ => rootfs/etc/nginx}/lua/vendor/lua-resty-http/t/04-trailers.t (100%) rename controllers/nginx/{ => rootfs/etc/nginx}/lua/vendor/lua-resty-http/t/05-stream.t (100%) rename controllers/nginx/{ => rootfs/etc/nginx}/lua/vendor/lua-resty-http/t/06-simpleinterface.t (100%) rename controllers/nginx/{ => rootfs/etc/nginx}/lua/vendor/lua-resty-http/t/07-keepalive.t (76%) rename controllers/nginx/{ => rootfs/etc/nginx}/lua/vendor/lua-resty-http/t/08-pipeline.t (100%) rename controllers/nginx/{ => rootfs/etc/nginx}/lua/vendor/lua-resty-http/t/09-ssl.t (100%) rename controllers/nginx/{ => rootfs/etc/nginx}/lua/vendor/lua-resty-http/t/10-clientbodyreader.t (100%) rename controllers/nginx/{ => rootfs/etc/nginx}/lua/vendor/lua-resty-http/t/11-proxy.t (100%) rename controllers/nginx/{ => rootfs/etc/nginx}/lua/vendor/lua-resty-http/t/12-case_insensitive_headers.t (100%) rename controllers/nginx/{ => rootfs/etc/nginx}/lua/vendor/lua-resty-http/t/13-default-path.t (100%) create mode 100644 controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/14-host-header.t create mode 100644 controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/cert/test.crt create mode 100644 controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/cert/test.key rename controllers/nginx/{ => rootfs/etc/nginx}/lua/vendor/lua-resty-http/util/lua-releng (100%) rename controllers/nginx/{default.conf => rootfs/etc/nginx/nginx.conf} (100%) rename controllers/nginx/{ => rootfs/etc/nginx/template}/nginx.tmpl (72%) create mode 100755 controllers/nginx/rootfs/ingress-controller/clean-nginx-conf.sh delete mode 100644 controllers/nginx/utils.go create mode 100644 core/pkg/cache/main.go rename {controllers/nginx/nginx => core/pkg/ingress/annotations}/auth/main.go (59%) rename {controllers/nginx/nginx => core/pkg/ingress/annotations}/auth/main_test.go (59%) rename {controllers/nginx/nginx => core/pkg/ingress/annotations}/authreq/main.go (53%) rename {controllers/nginx/nginx => core/pkg/ingress/annotations}/authreq/main_test.go (96%) create mode 100644 core/pkg/ingress/annotations/authtls/main.go create mode 100644 core/pkg/ingress/annotations/authtls/main_test.go rename {controllers/nginx/nginx => core/pkg/ingress/annotations}/cors/main.go (71%) rename {controllers/nginx/nginx => core/pkg/ingress/annotations}/healthcheck/main.go (50%) rename {controllers/nginx/nginx => core/pkg/ingress/annotations}/healthcheck/main_test.go (67%) rename {controllers/nginx/nginx => core/pkg/ingress/annotations}/ipwhitelist/main.go (69%) rename {controllers/nginx/nginx => core/pkg/ingress/annotations}/ipwhitelist/main_test.go (60%) create mode 100644 core/pkg/ingress/annotations/parser/main.go create mode 100644 core/pkg/ingress/annotations/parser/main_test.go create mode 100644 core/pkg/ingress/annotations/proxy/main.go create mode 100644 core/pkg/ingress/annotations/proxy/main_test.go rename {controllers/nginx/nginx => core/pkg/ingress/annotations}/ratelimit/main.go (78%) rename {controllers/nginx/nginx => core/pkg/ingress/annotations}/ratelimit/main_test.go (76%) rename {controllers/nginx/nginx => core/pkg/ingress/annotations}/rewrite/main.go (53%) rename {controllers/nginx/nginx => core/pkg/ingress/annotations}/rewrite/main_test.go (72%) rename {controllers/nginx/nginx => core/pkg/ingress/annotations}/secureupstream/main.go (69%) rename {controllers/nginx/nginx => core/pkg/ingress/annotations}/secureupstream/main_test.go (92%) create mode 100644 core/pkg/ingress/annotations/service/service.go create mode 100644 core/pkg/ingress/annotations/sslpassthrough/main.go create mode 100644 core/pkg/ingress/annotations/sslpassthrough/main_test.go create mode 100644 core/pkg/ingress/controller/backend_ssl.go create mode 100644 core/pkg/ingress/controller/controller.go create mode 100644 core/pkg/ingress/controller/launch.go create mode 100644 core/pkg/ingress/controller/metrics.go create mode 100644 core/pkg/ingress/controller/named_port.go create mode 100644 core/pkg/ingress/controller/util.go create mode 100644 core/pkg/ingress/controller/util_test.go create mode 100644 core/pkg/ingress/defaults/main.go create mode 100644 core/pkg/ingress/status/election.go create mode 100644 core/pkg/ingress/status/status.go create mode 100644 core/pkg/ingress/types.go create mode 100644 core/pkg/k8s/main.go create mode 100644 core/pkg/k8s/main_test.go create mode 100644 core/pkg/net/dns/dns.go create mode 100644 core/pkg/net/dns/dns_test.go create mode 100644 core/pkg/net/ssl/ssl.go rename {controllers/nginx/nginx => core/pkg/net/ssl}/ssl_test.go (94%) create mode 100644 core/pkg/strings/string.go create mode 100644 core/pkg/task/queue.go rename {controllers/nginx/nginx/template => core/pkg/watch}/file_watcher.go (78%) create mode 100644 core/pkg/watch/file_watcher_test.go create mode 100755 hack/e2e-internal/e2e-down.sh create mode 100755 hack/e2e-internal/e2e-env.sh create mode 100755 hack/e2e-internal/e2e-status.sh create mode 100755 hack/e2e-internal/e2e-up.sh create mode 100755 hack/e2e-internal/ginkgo-e2e.sh create mode 100644 hack/e2e.go diff --git a/controllers/gce/backends/backends_test.go b/controllers/gce/backends/backends_test.go index 538c0ce0a9..951cbb1cd9 100644 --- a/controllers/gce/backends/backends_test.go +++ b/controllers/gce/backends/backends_test.go @@ -32,7 +32,7 @@ const defaultZone = "zone-a" func newBackendPool(f BackendServices, fakeIGs instances.InstanceGroups, syncWithCloud bool) BackendPool { namer := &utils.Namer{} nodePool := instances.NewNodePool(fakeIGs) - nodePool.Init(&instances.FakeZoneLister{Items:[]string{defaultZone}}) + nodePool.Init(&instances.FakeZoneLister{Zones: []string{defaultZone}}) healthChecks := healthchecks.NewHealthChecker(healthchecks.NewFakeHealthChecks(), "/", namer) healthChecks.Init(&healthchecks.FakeHealthCheckGetter{DefaultHealthCheck: nil}) return NewBackendPool( diff --git a/controllers/nginx/.gitignore b/controllers/nginx/.gitignore index 47f069f7a5..f7fc6d3ef7 100644 --- a/controllers/nginx/.gitignore +++ b/controllers/nginx/.gitignore @@ -1 +1,2 @@ -nginx-ingress-controller +rootfs/nginx-ingress-controller +*/**/.coverprofile \ No newline at end of file diff --git a/controllers/nginx/Changelog.md b/controllers/nginx/Changelog.md index 0bb7aeec39..60fd919fe6 100644 --- a/controllers/nginx/Changelog.md +++ b/controllers/nginx/Changelog.md @@ -1,5 +1,33 @@ Changelog +### 0.9 + +- [X] [#1498](https://github.com/kubernetes/contrib/pull/1498) Refactoring of template handling +- [X] [#1571](https://github.com/kubernetes/contrib/pull/1571) use POD_NAMESPACE as a namespace in cli parameters +- [X] [#1591](https://github.com/kubernetes/contrib/pull/1591) Always listen on port 443, even without ingress rules +- [X] [#1596](https://github.com/kubernetes/contrib/pull/1596) Adapt nginx hash sizes to the number of ingress +- [X] [#1653](https://github.com/kubernetes/contrib/pull/1653) Update image version +- [X] [#1672](https://github.com/kubernetes/contrib/pull/1672) Add firewall rules and ing class clarifications +- [X] [#1711](https://github.com/kubernetes/contrib/pull/1711) Add function helpers to nginx template +- [X] [#1743](https://github.com/kubernetes/contrib/pull/1743) Allow customisation of the nginx proxy_buffer_size directive via ConfigMap +- [X] [#1749](https://github.com/kubernetes/contrib/pull/1749) Readiness probe that works behind a CP lb +- [X] [#1751](https://github.com/kubernetes/contrib/pull/1751) Add the name of the upstream in the log +- [X] [#1758](https://github.com/kubernetes/contrib/pull/1758) Update nginx to 1.11.4 +- [X] [#1759](https://github.com/kubernetes/contrib/pull/1759) Add support for default backend in Ingress rule +- [X] [#1762](https://github.com/kubernetes/contrib/pull/1762) Add cloud detection +- [X] [#1766](https://github.com/kubernetes/contrib/pull/1766) Clarify the controller uses endpoints and not services +- [X] [#1767](https://github.com/kubernetes/contrib/pull/1767) Update godeps +- [X] [#1772](https://github.com/kubernetes/contrib/pull/1772) Avoid replacing nginx.conf file if the new configuration is invalid +- [X] [#1773](https://github.com/kubernetes/contrib/pull/1773) Add annotation to add CORS support +- [X] [#1786](https://github.com/kubernetes/contrib/pull/1786) Add docs about go template +- [X] [#1796](https://github.com/kubernetes/contrib/pull/1796) Add external authentication support using auth_request +- [X] [#1802](https://github.com/kubernetes/contrib/pull/1802) Initialize proxy_upstream_name variable +- [X] [#1806](https://github.com/kubernetes/contrib/pull/1806) Add docs about the log format +- [X] [#1808](https://github.com/kubernetes/contrib/pull/1808) WebSocket documentation +- [X] [#1847](https://github.com/kubernetes/contrib/pull/1847) Change structure of packages +- [X] Add annotation for custom upstream timeouts +- [X] Mutual TLS auth (https://github.com/kubernetes/contrib/issues/1870) + ### 0.8.3 - [X] [#1450](https://github.com/kubernetes/contrib/pull/1450) Check for errors in nginx template diff --git a/controllers/nginx/Makefile b/controllers/nginx/Makefile index c5eca4838b..4d701a7742 100644 --- a/controllers/nginx/Makefile +++ b/controllers/nginx/Makefile @@ -1,25 +1,52 @@ all: push +BUILDTAGS= + # 0.0 shouldn't clobber any release builds -TAG = 0.8.3 -PREFIX = gcr.io/google_containers/nginx-ingress-controller +RELEASE?=0.0 +PREFIX?=gcr.io/google_containers/nginx-ingress-controller +GOOS?=linux REPO_INFO=$(shell git config --get remote.origin.url) -ifndef VERSION - VERSION := git-$(shell git rev-parse --short HEAD) +ifndef COMMIT + COMMIT := git-$(shell git rev-parse --short HEAD) endif -controller: controller.go clean - CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags \ - "-s -w -X main.version=${VERSION} -X main.gitRepo=${REPO_INFO}" \ - -o nginx-ingress-controller +PKG=k8s.io/ingress/controllers/nginx + +build: clean + CGO_ENABLED=0 GOOS=${GOOS} go build -a -installsuffix cgo \ + -ldflags "-s -w -X ${PKG}/pkg/version.RELEASE=${RELEASE} -X ${PKG}/pkg/version.COMMIT=${COMMIT} -X ${PKG}/pkg/version.REPO=${REPO_INFO}" \ + -o rootfs/nginx-ingress-controller ${PKG}/pkg/cmd/controller + +container: + docker build -t $(PREFIX):$(RELEASE) rootfs + +push: + gcloud docker push $(PREFIX):$(RELEASE) + +fmt: + @echo "+ $@" + @go list -f '{{if len .TestGoFiles}}"gofmt -s -l {{.Dir}}"{{end}}' $(shell go list ${PKG}/... | grep -v vendor) | xargs -L 1 sh -c + +lint: + @echo "+ $@" + @go list -f '{{if len .TestGoFiles}}"golint {{.Dir}}/..."{{end}}' $(shell go list ${PKG}/... | grep -v vendor) | xargs -L 1 sh -c + +test: fmt lint vet + @echo "+ $@" + @go test -v -race -tags "$(BUILDTAGS) cgo" $(shell go list ${PKG}/... | grep -v vendor) -container: controller - docker build -t $(PREFIX):$(TAG) . +cover: + @echo "+ $@" + @go list -f '{{if len .TestGoFiles}}"go test -coverprofile={{.Dir}}/.coverprofile {{.ImportPath}}"{{end}}' $(shell go list ${PKG}/... | grep -v vendor) | xargs -L 1 sh -c + gover + goveralls -coverprofile=gover.coverprofile -service travis-ci -repotoken ${COVERALLS_TOKEN} -push: container - gcloud docker push $(PREFIX):$(TAG) +vet: + @echo "+ $@" + @go vet $(shell go list ${PKG}/... | grep -v vendor) clean: rm -f nginx-ingress-controller diff --git a/controllers/nginx/README.md b/controllers/nginx/README.md index 67b70912a9..5af7c5e324 100644 --- a/controllers/nginx/README.md +++ b/controllers/nginx/README.md @@ -1,12 +1,18 @@ + +[![Build Status](https://travis-ci.org/aledbf/ingress-controller.svg?branch=master)](https://travis-ci.org/aledbf/ingress-controller) +[![Coverage Status](https://coveralls.io/repos/github/aledbf/ingress-controller/badge.svg?branch=master)](https://coveralls.io/github/aledbf/ingress-controller?branch=master) +[![Go Report Card](https://goreportcard.com/badge/github.com/aledbf/ingress-controller)](https://goreportcard.com/report/github.com/aledbf/ingress-controller) + # Nginx Ingress Controller This is an nginx Ingress controller that uses [ConfigMap](https://github.com/kubernetes/kubernetes/blob/master/docs/design/configmap.md) to store the nginx configuration. See [Ingress controller documentation](../README.md) for details on how it works. ## Contents +* [Recent changes](#recent-changes) * [Conventions](#conventions) * [Requirements](#what-it-provides) -* [Dry running](#dry-running-the-ingress-controller) * [Deployment](#deployment) +* [Health checks](#health-checks) * [HTTP](#http) * [HTTPS](#https) * [Default SSL Certificate](#default-ssl-certificate) @@ -16,6 +22,7 @@ This is an nginx Ingress controller that uses [ConfigMap](https://github.com/kub * [TCP Services](#exposing-tcp-services) * [UDP Services](#exposing-udp-services) * [Proxy Protocol](#proxy-protocol) +* [Service Integration](#service-integration) * [NGINX customization](configuration.md) * [NGINX status page](#nginx-status-page) * [Running multiple ingress controllers](#running-multiple-ingress-controllers) @@ -25,9 +32,15 @@ This is an nginx Ingress controller that uses [ConfigMap](https://github.com/kub * [Local cluster](#local-cluster) * [Debug & Troubleshooting](#troubleshooting) * [Why endpoints and not services?](#why-endpoints-and-not-services) +* [Metrics](#metrics) * [Limitations](#limitations) * [NGINX Notes](#nginx-notes) +## Recent changes + +Change history is available in [CHANGELOG.md](CHANGELOG.md) + + ## Conventions Anytime we reference a tls secret, we mean (x509, pem encoded, RSA 2048, etc). You can generate such a certificate with: @@ -35,21 +48,10 @@ Anytime we reference a tls secret, we mean (x509, pem encoded, RSA 2048, etc). Y and create the secret via `kubectl create secret tls --key file --cert file` - ## Requirements - Default backend [404-server](https://github.com/kubernetes/contrib/tree/master/404-server) -## Dry running the Ingress controller - -Before deploying the controller to production you might want to run it outside the cluster and observe it. - -```console -$ make controller -$ mkdir /etc/nginx-ssl -$ ./nginx-ingress-controller --running-in-cluster=false --default-backend-service=kube-system/default-http-backend -``` - ## Deployment First create a default backend: @@ -64,6 +66,15 @@ Loadbalancers are created via a ReplicationController or Daemonset: $ kubectl create -f examples/default/rc-default.yaml ``` +## Health checks + +The proveded examples in the Ingress controller use a `readiness` and `liveness` probe. By default the URL is `/healthz` and the port `18080`. +Using the flag `--health-check-path` is possible to specify a custom path. +In some environments only port 80 is allowed to enable health checks. For this reason the Ingress controller exposes this path in the default server. + +If PROXY protocol is enabled the health check must use the default port `18080`. This is required because Kubernetes probes do not understand PROXY protocol. + + ## HTTP First we need to deploy some application to publish. To keep this simple we will use the [echoheaders app](https://github.com/kubernetes/contrib/blob/master/ingress/echoheaders/echo-app.yaml) that just returns information about the http request as output @@ -141,6 +152,7 @@ Please follow [test.sh](https://github.com/bprashanth/Ingress/blob/master/exampl Check the [example](examples/tls/README.md) + ### Default SSL Certificate NGINX provides the option [server name](http://nginx.org/en/docs/http/server_names.html) as a catch-all in case of requests that do not match one of the configured server names. This configuration works without issues for HTTP traffic. In case of HTTPS NGINX requires a certificate. For this reason the Ingress controller provides the flag `--default-ssl-certificate`. The secret behind this flag contains the default certificate to be used in the mentioned case. @@ -325,6 +337,12 @@ Amongst others [ELBs in AWS](http://docs.aws.amazon.com/ElasticLoadBalancing/lat Please check the [proxy-protocol](examples/proxy-protocol/) example +## Service Integration + +On clouds like AWS or GCE, using a service with `Type=LoadBalancer` allows the default kubernetes integration, which can save a lot of work. +By passing the `--publish-service` argument to the controller, the ingress status will be updated with the load balancer configuration of the service, rather than the IP/s of the node/s. + + ### Custom errors In case of an error in a request the body of the response is obtained from the `default backend`. Each request to the default backend includes two headers: @@ -427,14 +445,12 @@ I0316 12:24:37.610073 1 command.go:69] change in configuration detected. R - `--v=3` shows details about the service, Ingress rule, endpoint changes and it dumps the nginx configuration in JSON format - `--v=5` configures NGINX in [debug mode](http://nginx.org/en/docs/debugging_log.html) +### Metrics - -*These issues were encountered in past versions of Kubernetes:* - -[1.2.0-alpha7 deployment](https://github.com/kubernetes/kubernetes/blob/master/docs/getting-started-guides/docker.md): - -* make setup-files.sh file in hypercube does not provide 10.0.0.1 IP to make-ca-certs, resulting in CA certs that are issued to the external cluster IP address rather then 10.0.0.1 -> this results in nginx-third-party-lb appearing to get stuck at "Utils.go:177 - Waiting for default/default-http-backend" in the docker logs. Kubernetes will eventually kill the container before nginx-third-party-lb times out with a message indicating that the CA certificate issuer is invalid (wrong ip), to verify this add zeros to the end of initialDelaySeconds and timeoutSeconds and reload the RC, and docker will log this error before kubernetes kills the container. - * To fix the above, setup-files.sh must be patched before the cluster is inited (refer to https://github.com/kubernetes/kubernetes/pull/21504) +Using the doc [Instrumenting Kubernetes with a new metric](https://github.com/kubernetes/kubernetes/blob/master/docs/devel/instrumentation.md#instrumenting-kubernetes-with-a-new-metric) the Ingress controller +exposes the registered metrics via HTTP. Besides the default metrics provided by Prometheus is possible to get the number of reloads `reload_operations` and reloads with error `reload_operations_errors`, +ie error in validation in the configuration file before the reload. The metrics are exposed in port `10254` and path `/metrics`. +Using curl: `curl -v :10254/metrics` ### Limitations @@ -452,11 +468,3 @@ The NGINX ingress controller does not uses [Services](http://kubernetes.io/docs/ Since `gcr.io/google_containers/nginx-slim:0.8` NGINX contains the next patches: - Dynamic TLS record size [nginx__dynamic_tls_records.patch](https://blog.cloudflare.com/optimizing-tls-over-tcp-to-reduce-latency/) NGINX provides the parameter `ssl_buffer_size` to adjust the size of the buffer. Default value in NGINX is 16KB. The ingress controller changes the default to 4KB. This improves the [TLS Time To First Byte (TTTFB)](https://www.igvita.com/2013/12/16/optimizing-nginx-tls-time-to-first-byte/) but the size is fixed. This patches adapts the size of the buffer to the content is being served helping to improve the perceived latency. - -- Add SPDY support back to Nginx with HTTP/2 [nginx_1_9_15_http2_spdy.patch](https://github.com/cloudflare/sslconfig/pull/36) -At the same NGINX introduced HTTP/2 support for SPDY was removed. This patch add support for SPDY without compromising HTTP/2 support using the Application-Layer Protocol Negotiation (ALPN) or Next Protocol Negotiation (NPN) Transport Layer Security (TLS) extension to negotiate what protocol the server and client support -``` -openssl s_client -servername www.my-site.com -connect www.my-site.com:443 -nextprotoneg '' -CONNECTED(00000003) -Protocols advertised by server: h2, spdy/3.1, http/1.1 -``` diff --git a/controllers/nginx/controller.go b/controllers/nginx/controller.go deleted file mode 100644 index 2e9cdf305d..0000000000 --- a/controllers/nginx/controller.go +++ /dev/null @@ -1,1244 +0,0 @@ -/* -Copyright 2015 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 main - -import ( - "encoding/json" - "fmt" - "reflect" - "sort" - "strconv" - "strings" - "sync" - "time" - - "github.com/golang/glog" - - "k8s.io/kubernetes/pkg/api" - podutil "k8s.io/kubernetes/pkg/api/pod" - "k8s.io/kubernetes/pkg/apis/extensions" - "k8s.io/kubernetes/pkg/client/cache" - "k8s.io/kubernetes/pkg/client/record" - client "k8s.io/kubernetes/pkg/client/unversioned" - "k8s.io/kubernetes/pkg/controller/framework" - "k8s.io/kubernetes/pkg/labels" - "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/util/intstr" - "k8s.io/kubernetes/pkg/watch" - - "k8s.io/contrib/ingress/controllers/nginx/nginx" - "k8s.io/contrib/ingress/controllers/nginx/nginx/auth" - "k8s.io/contrib/ingress/controllers/nginx/nginx/authreq" - "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/ingress" - "k8s.io/contrib/ingress/controllers/nginx/nginx/ipwhitelist" - "k8s.io/contrib/ingress/controllers/nginx/nginx/ratelimit" - "k8s.io/contrib/ingress/controllers/nginx/nginx/rewrite" - "k8s.io/contrib/ingress/controllers/nginx/nginx/secureupstream" -) - -const ( - defUpstreamName = "upstream-default-backend" - defServerName = "_" - namedPortAnnotation = "ingress.kubernetes.io/named-ports" - podStoreSyncedPollPeriod = 1 * time.Second - rootLocation = "/" -) - -var ( - keyFunc = framework.DeletionHandlingMetaNamespaceKeyFunc -) - -type namedPortMapping map[string]string - -// getPort returns the port defined in a named port -func (npm namedPortMapping) getPort(name string) (string, bool) { - val, ok := npm.getPortMappings()[name] - return val, ok -} - -// getPortMappings returns the map containing the -// mapping of named port names and the port number -func (npm namedPortMapping) getPortMappings() map[string]string { - data := npm[namedPortAnnotation] - var mapping map[string]string - if data == "" { - return mapping - } - if err := json.Unmarshal([]byte(data), &mapping); err != nil { - glog.Errorf("unexpected error reading annotations: %v", err) - } - - return mapping -} - -// loadBalancerController watches the kubernetes api and adds/removes services -// from the loadbalancer -type loadBalancerController struct { - client *client.Client - - ingController *framework.Controller - endpController *framework.Controller - svcController *framework.Controller - secrController *framework.Controller - mapController *framework.Controller - - ingLister StoreToIngressLister - svcLister cache.StoreToServiceLister - endpLister cache.StoreToEndpointsLister - secrLister StoreToSecretsLister - mapLister StoreToConfigmapLister - - nginx *nginx.Manager - podInfo *podInfo - - defaultSvc string - - nxgConfigMap string - tcpConfigMap string - udpConfigMap string - - defSSLCertificate string - defHealthzURL string - - recorder record.EventRecorder - - syncQueue *taskQueue - - // taskQueue used to update the status of the Ingress rules. - // this avoids a sync execution in the ResourceEventHandlerFuncs - ingQueue *taskQueue - - // stopLock is used to enforce only a single call to Stop is active. - // Needed because we allow stopping through an http endpoint and - // allowing concurrent stoppers leads to stack traces. - stopLock sync.Mutex - shutdown bool - stopCh chan struct{} -} - -// newLoadBalancerController creates a controller for nginx loadbalancer -func newLoadBalancerController(kubeClient *client.Client, resyncPeriod time.Duration, - defaultSvc, namespace, nxgConfigMapName, tcpConfigMapName, udpConfigMapName, - defSSLCertificate, defHealthzURL string, runtimeInfo *podInfo) (*loadBalancerController, error) { - - eventBroadcaster := record.NewBroadcaster() - eventBroadcaster.StartLogging(glog.Infof) - eventBroadcaster.StartRecordingToSink(kubeClient.Events(namespace)) - - lbc := loadBalancerController{ - client: kubeClient, - stopCh: make(chan struct{}), - podInfo: runtimeInfo, - nginx: nginx.NewManager(kubeClient), - nxgConfigMap: nxgConfigMapName, - tcpConfigMap: tcpConfigMapName, - udpConfigMap: udpConfigMapName, - defSSLCertificate: defSSLCertificate, - defaultSvc: defaultSvc, - defHealthzURL: defHealthzURL, - recorder: eventBroadcaster.NewRecorder(api.EventSource{ - Component: "nginx-ingress-controller", - }), - } - - lbc.syncQueue = NewTaskQueue(lbc.sync) - lbc.ingQueue = NewTaskQueue(lbc.updateIngressStatus) - - ingEventHandler := framework.ResourceEventHandlerFuncs{ - AddFunc: func(obj interface{}) { - addIng := obj.(*extensions.Ingress) - if !isNGINXIngress(addIng) { - glog.Infof("Ignoring add for ingress %v based on annotation %v", addIng.Name, ingressClassKey) - return - } - lbc.recorder.Eventf(addIng, api.EventTypeNormal, "CREATE", fmt.Sprintf("%s/%s", addIng.Namespace, addIng.Name)) - lbc.ingQueue.enqueue(obj) - lbc.syncQueue.enqueue(obj) - }, - DeleteFunc: func(obj interface{}) { - delIng := obj.(*extensions.Ingress) - if !isNGINXIngress(delIng) { - glog.Infof("Ignoring add for ingress %v based on annotation %v", delIng.Name, ingressClassKey) - return - } - lbc.recorder.Eventf(delIng, api.EventTypeNormal, "DELETE", fmt.Sprintf("%s/%s", delIng.Namespace, delIng.Name)) - lbc.syncQueue.enqueue(obj) - }, - UpdateFunc: func(old, cur interface{}) { - curIng := cur.(*extensions.Ingress) - if !isNGINXIngress(curIng) { - return - } - if !reflect.DeepEqual(old, cur) { - upIng := cur.(*extensions.Ingress) - lbc.recorder.Eventf(upIng, api.EventTypeNormal, "UPDATE", fmt.Sprintf("%s/%s", upIng.Namespace, upIng.Name)) - lbc.ingQueue.enqueue(cur) - lbc.syncQueue.enqueue(cur) - } - }, - } - - secrEventHandler := framework.ResourceEventHandlerFuncs{ - AddFunc: func(obj interface{}) { - addSecr := obj.(*api.Secret) - if lbc.secrReferenced(addSecr.Namespace, addSecr.Name) { - lbc.recorder.Eventf(addSecr, api.EventTypeNormal, "CREATE", fmt.Sprintf("%s/%s", addSecr.Namespace, addSecr.Name)) - lbc.syncQueue.enqueue(obj) - } - }, - DeleteFunc: func(obj interface{}) { - delSecr := obj.(*api.Secret) - if lbc.secrReferenced(delSecr.Namespace, delSecr.Name) { - lbc.recorder.Eventf(delSecr, api.EventTypeNormal, "DELETE", fmt.Sprintf("%s/%s", delSecr.Namespace, delSecr.Name)) - lbc.syncQueue.enqueue(obj) - } - }, - UpdateFunc: func(old, cur interface{}) { - if !reflect.DeepEqual(old, cur) { - upSecr := cur.(*api.Secret) - if lbc.secrReferenced(upSecr.Namespace, upSecr.Name) { - lbc.recorder.Eventf(upSecr, api.EventTypeNormal, "UPDATE", fmt.Sprintf("%s/%s", upSecr.Namespace, upSecr.Name)) - lbc.syncQueue.enqueue(cur) - } - } - }, - } - - eventHandler := framework.ResourceEventHandlerFuncs{ - AddFunc: func(obj interface{}) { - lbc.syncQueue.enqueue(obj) - }, - DeleteFunc: func(obj interface{}) { - lbc.syncQueue.enqueue(obj) - }, - UpdateFunc: func(old, cur interface{}) { - if !reflect.DeepEqual(old, cur) { - lbc.syncQueue.enqueue(cur) - } - }, - } - - mapEventHandler := framework.ResourceEventHandlerFuncs{ - UpdateFunc: func(old, cur interface{}) { - if !reflect.DeepEqual(old, cur) { - upCmap := cur.(*api.ConfigMap) - mapKey := fmt.Sprintf("%s/%s", upCmap.Namespace, upCmap.Name) - // updates to configuration configmaps can trigger an update - if mapKey == lbc.nxgConfigMap || mapKey == lbc.tcpConfigMap || mapKey == lbc.udpConfigMap { - lbc.recorder.Eventf(upCmap, api.EventTypeNormal, "UPDATE", mapKey) - lbc.syncQueue.enqueue(cur) - } - } - }, - } - - lbc.ingLister.Store, lbc.ingController = framework.NewInformer( - &cache.ListWatch{ - ListFunc: ingressListFunc(lbc.client, namespace), - WatchFunc: ingressWatchFunc(lbc.client, namespace), - }, - &extensions.Ingress{}, resyncPeriod, ingEventHandler) - - lbc.endpLister.Store, lbc.endpController = framework.NewInformer( - &cache.ListWatch{ - ListFunc: endpointsListFunc(lbc.client, namespace), - WatchFunc: endpointsWatchFunc(lbc.client, namespace), - }, - &api.Endpoints{}, resyncPeriod, eventHandler) - - lbc.svcLister.Store, lbc.svcController = framework.NewInformer( - &cache.ListWatch{ - ListFunc: serviceListFunc(lbc.client, namespace), - WatchFunc: serviceWatchFunc(lbc.client, namespace), - }, - &api.Service{}, resyncPeriod, framework.ResourceEventHandlerFuncs{}) - - lbc.secrLister.Store, lbc.secrController = framework.NewInformer( - &cache.ListWatch{ - ListFunc: secretsListFunc(lbc.client, namespace), - WatchFunc: secretsWatchFunc(lbc.client, namespace), - }, - &api.Secret{}, resyncPeriod, secrEventHandler) - - lbc.mapLister.Store, lbc.mapController = framework.NewInformer( - &cache.ListWatch{ - ListFunc: mapListFunc(lbc.client, namespace), - WatchFunc: mapWatchFunc(lbc.client, namespace), - }, - &api.ConfigMap{}, resyncPeriod, mapEventHandler) - - return &lbc, nil -} - -func ingressListFunc(c *client.Client, ns string) func(api.ListOptions) (runtime.Object, error) { - return func(opts api.ListOptions) (runtime.Object, error) { - return c.Extensions().Ingress(ns).List(opts) - } -} - -func ingressWatchFunc(c *client.Client, ns string) func(options api.ListOptions) (watch.Interface, error) { - return func(options api.ListOptions) (watch.Interface, error) { - return c.Extensions().Ingress(ns).Watch(options) - } -} - -func serviceListFunc(c *client.Client, ns string) func(api.ListOptions) (runtime.Object, error) { - return func(opts api.ListOptions) (runtime.Object, error) { - return c.Services(ns).List(opts) - } -} - -func serviceWatchFunc(c *client.Client, ns string) func(options api.ListOptions) (watch.Interface, error) { - return func(options api.ListOptions) (watch.Interface, error) { - return c.Services(ns).Watch(options) - } -} - -func endpointsListFunc(c *client.Client, ns string) func(api.ListOptions) (runtime.Object, error) { - return func(opts api.ListOptions) (runtime.Object, error) { - return c.Endpoints(ns).List(opts) - } -} - -func endpointsWatchFunc(c *client.Client, ns string) func(options api.ListOptions) (watch.Interface, error) { - return func(options api.ListOptions) (watch.Interface, error) { - return c.Endpoints(ns).Watch(options) - } -} - -func secretsListFunc(c *client.Client, ns string) func(api.ListOptions) (runtime.Object, error) { - return func(opts api.ListOptions) (runtime.Object, error) { - return c.Secrets(ns).List(opts) - } -} - -func secretsWatchFunc(c *client.Client, ns string) func(options api.ListOptions) (watch.Interface, error) { - return func(options api.ListOptions) (watch.Interface, error) { - return c.Secrets(ns).Watch(options) - } -} - -func mapListFunc(c *client.Client, ns string) func(api.ListOptions) (runtime.Object, error) { - return func(opts api.ListOptions) (runtime.Object, error) { - return c.ConfigMaps(ns).List(opts) - } -} - -func mapWatchFunc(c *client.Client, ns string) func(options api.ListOptions) (watch.Interface, error) { - return func(options api.ListOptions) (watch.Interface, error) { - return c.ConfigMaps(ns).Watch(options) - } -} - -func (lbc *loadBalancerController) controllersInSync() bool { - return lbc.ingController.HasSynced() && - lbc.svcController.HasSynced() && - lbc.endpController.HasSynced() && - lbc.secrController.HasSynced() && - lbc.mapController.HasSynced() -} - -func (lbc *loadBalancerController) getConfigMap(ns, name string) (*api.ConfigMap, error) { - // TODO: check why lbc.mapLister.Store.GetByKey(mapKey) is not stable (random content) - return lbc.client.ConfigMaps(ns).Get(name) -} - -func (lbc *loadBalancerController) getTCPConfigMap(ns, name string) (*api.ConfigMap, error) { - return lbc.getConfigMap(ns, name) -} - -func (lbc *loadBalancerController) getUDPConfigMap(ns, name string) (*api.ConfigMap, error) { - return lbc.getConfigMap(ns, name) -} - -// checkSvcForUpdate verifies if one of the running pods for a service contains -// named port. If the annotation in the service does not exists or is not equals -// to the port mapping obtained from the pod the service must be updated to reflect -// the current state -func (lbc *loadBalancerController) checkSvcForUpdate(svc *api.Service) (map[string]string, error) { - // get the pods associated with the service - // TODO: switch this to a watch - pods, err := lbc.client.Pods(svc.Namespace).List(api.ListOptions{ - LabelSelector: labels.Set(svc.Spec.Selector).AsSelector(), - }) - - namedPorts := map[string]string{} - if err != nil { - return namedPorts, fmt.Errorf("error searching service pods %v/%v: %v", svc.Namespace, svc.Name, err) - } - - if len(pods.Items) == 0 { - return namedPorts, nil - } - - // we need to check only one pod searching for named ports - pod := &pods.Items[0] - glog.V(4).Infof("checking pod %v/%v for named port information", pod.Namespace, pod.Name) - for i := range svc.Spec.Ports { - servicePort := &svc.Spec.Ports[i] - - _, err := strconv.Atoi(servicePort.TargetPort.StrVal) - if err != nil { - portNum, err := podutil.FindPort(pod, servicePort) - if err != nil { - glog.V(4).Infof("failed to find port for service %s/%s: %v", svc.Namespace, svc.Name, err) - continue - } - - if servicePort.TargetPort.StrVal == "" { - continue - } - - namedPorts[servicePort.TargetPort.StrVal] = fmt.Sprintf("%v", portNum) - } - } - - if svc.ObjectMeta.Annotations == nil { - svc.ObjectMeta.Annotations = map[string]string{} - } - - curNamedPort := svc.ObjectMeta.Annotations[namedPortAnnotation] - if len(namedPorts) > 0 && !reflect.DeepEqual(curNamedPort, namedPorts) { - data, _ := json.Marshal(namedPorts) - - newSvc, err := lbc.client.Services(svc.Namespace).Get(svc.Name) - if err != nil { - return namedPorts, fmt.Errorf("error getting service %v/%v: %v", svc.Namespace, svc.Name, err) - } - - if newSvc.ObjectMeta.Annotations == nil { - newSvc.ObjectMeta.Annotations = map[string]string{} - } - - newSvc.ObjectMeta.Annotations[namedPortAnnotation] = string(data) - glog.Infof("updating service %v with new named port mappings", svc.Name) - _, err = lbc.client.Services(svc.Namespace).Update(newSvc) - if err != nil { - return namedPorts, fmt.Errorf("error syncing service %v/%v: %v", svc.Namespace, svc.Name, err) - } - - return newSvc.ObjectMeta.Annotations, nil - } - - return namedPorts, nil -} - -func (lbc *loadBalancerController) sync(key string) error { - if !lbc.controllersInSync() { - time.Sleep(podStoreSyncedPollPeriod) - return fmt.Errorf("deferring sync till endpoints controller has synced") - } - - // by default no custom configuration configmap - cfg := &api.ConfigMap{} - - if lbc.nxgConfigMap != "" { - // Search for custom configmap (defined in main args) - var err error - ns, name, _ := parseNsName(lbc.nxgConfigMap) - cfg, err = lbc.getConfigMap(ns, name) - if err != nil { - return fmt.Errorf("unexpected error searching configmap %v: %v", lbc.nxgConfigMap, err) - } - } - - ngxConfig := lbc.nginx.ReadConfig(cfg) - ngxConfig.HealthzURL = lbc.defHealthzURL - - ings := lbc.ingLister.Store.List() - upstreams, servers := lbc.getUpstreamServers(ngxConfig, ings) - - return lbc.nginx.CheckAndReload(ngxConfig, ingress.Configuration{ - Upstreams: upstreams, - Servers: servers, - TCPUpstreams: lbc.getTCPServices(), - UDPUpstreams: lbc.getUDPServices(), - }) -} - -func (lbc *loadBalancerController) updateIngressStatus(key string) error { - if !lbc.controllersInSync() { - time.Sleep(podStoreSyncedPollPeriod) - return fmt.Errorf("deferring sync till endpoints controller has synced") - } - - obj, ingExists, err := lbc.ingLister.Store.GetByKey(key) - if err != nil { - return err - } - - if !ingExists { - // TODO: what's the correct behavior here? - return nil - } - - ing := obj.(*extensions.Ingress) - - ingClient := lbc.client.Extensions().Ingress(ing.Namespace) - - currIng, err := ingClient.Get(ing.Name) - if err != nil { - return fmt.Errorf("unexpected error searching Ingress %v/%v: %v", ing.Namespace, ing.Name, err) - } - - lbIPs := ing.Status.LoadBalancer.Ingress - if !lbc.isStatusIPDefined(lbIPs) { - glog.Infof("Updating loadbalancer %v/%v with IP %v", ing.Namespace, ing.Name, lbc.podInfo.NodeIP) - currIng.Status.LoadBalancer.Ingress = append(currIng.Status.LoadBalancer.Ingress, api.LoadBalancerIngress{ - IP: lbc.podInfo.NodeIP, - }) - if _, err := ingClient.UpdateStatus(currIng); err != nil { - lbc.recorder.Eventf(currIng, api.EventTypeWarning, "UPDATE", "error: %v", err) - return err - } - - lbc.recorder.Eventf(currIng, api.EventTypeNormal, "CREATE", "ip: %v", lbc.podInfo.NodeIP) - } - - return nil -} - -func (lbc *loadBalancerController) isStatusIPDefined(lbings []api.LoadBalancerIngress) bool { - for _, lbing := range lbings { - if lbing.IP == lbc.podInfo.NodeIP { - return true - } - } - - return false -} - -func (lbc *loadBalancerController) getTCPServices() []*ingress.Location { - if lbc.tcpConfigMap == "" { - // no configmap for TCP services - return []*ingress.Location{} - } - - ns, name, err := parseNsName(lbc.tcpConfigMap) - if err != nil { - glog.Warningf("%v", err) - return []*ingress.Location{} - } - tcpMap, err := lbc.getTCPConfigMap(ns, name) - if err != nil { - glog.V(3).Infof("no configured tcp services found: %v", err) - return []*ingress.Location{} - } - - return lbc.getStreamServices(tcpMap.Data, api.ProtocolTCP) -} - -func (lbc *loadBalancerController) getUDPServices() []*ingress.Location { - if lbc.udpConfigMap == "" { - // no configmap for TCP services - return []*ingress.Location{} - } - - ns, name, err := parseNsName(lbc.udpConfigMap) - if err != nil { - glog.Warningf("%v", err) - return []*ingress.Location{} - } - tcpMap, err := lbc.getUDPConfigMap(ns, name) - if err != nil { - glog.V(3).Infof("no configured tcp services found: %v", err) - return []*ingress.Location{} - } - - return lbc.getStreamServices(tcpMap.Data, api.ProtocolUDP) -} - -func (lbc *loadBalancerController) getStreamServices(data map[string]string, proto api.Protocol) []*ingress.Location { - var svcs []*ingress.Location - // k -> port to expose in nginx - // v -> /: - for k, v := range data { - port, err := strconv.Atoi(k) - if err != nil { - glog.Warningf("%v is not valid as a TCP port", k) - continue - } - - // this ports are required for NGINX - if k == "80" || k == "443" || k == "8181" { - glog.Warningf("port %v cannot be used for TCP or UDP services. Is reserved for NGINX", k) - continue - } - - nsSvcPort := strings.Split(v, ":") - if len(nsSvcPort) != 2 { - glog.Warningf("invalid format (namespace/name:port) '%v'", k) - continue - } - - nsName := nsSvcPort[0] - svcPort := nsSvcPort[1] - - svcNs, svcName, err := parseNsName(nsName) - if err != nil { - glog.Warningf("%v", err) - continue - } - - svcObj, svcExists, err := lbc.svcLister.Store.GetByKey(nsName) - if err != nil { - glog.Warningf("error getting service %v: %v", nsName, err) - continue - } - - if !svcExists { - glog.Warningf("service %v was not found", nsName) - continue - } - - svc := svcObj.(*api.Service) - - var endps []ingress.UpstreamServer - targetPort, err := strconv.Atoi(svcPort) - if err != nil { - for _, sp := range svc.Spec.Ports { - if sp.Name == svcPort { - endps = lbc.getEndpoints(svc, sp.TargetPort, proto, &healthcheck.Upstream{}) - break - } - } - } else { - // we need to use the TargetPort (where the endpoints are running) - for _, sp := range svc.Spec.Ports { - if sp.Port == int32(targetPort) { - endps = lbc.getEndpoints(svc, sp.TargetPort, proto, &healthcheck.Upstream{}) - break - } - } - } - - // tcp upstreams cannot contain empty upstreams and there is no - // default backend equivalent for TCP - if len(endps) == 0 { - glog.Warningf("service %v/%v does not have any active endpoints", svcNs, svcName) - continue - } - - svcs = append(svcs, &ingress.Location{ - Path: k, - Upstream: ingress.Upstream{ - Name: fmt.Sprintf("%v-%v-%v", svcNs, svcName, port), - Backends: endps, - }, - }) - } - - return svcs -} - -// getDefaultUpstream returns an NGINX upstream associated with the -// default backend service. In case of error retrieving information -// configure the upstream to return http code 503. -func (lbc *loadBalancerController) getDefaultUpstream() *ingress.Upstream { - upstream := &ingress.Upstream{ - Name: defUpstreamName, - } - svcKey := lbc.defaultSvc - svcObj, svcExists, err := lbc.svcLister.Store.GetByKey(svcKey) - if err != nil { - glog.Warningf("unexpected error searching the default backend %v: %v", lbc.defaultSvc, err) - upstream.Backends = append(upstream.Backends, nginx.NewDefaultServer()) - return upstream - } - - if !svcExists { - glog.Warningf("service %v does not exists", svcKey) - upstream.Backends = append(upstream.Backends, nginx.NewDefaultServer()) - return upstream - } - - svc := svcObj.(*api.Service) - - endps := lbc.getEndpoints(svc, svc.Spec.Ports[0].TargetPort, api.ProtocolTCP, &healthcheck.Upstream{}) - if len(endps) == 0 { - glog.Warningf("service %v does not have any active endpoints", svcKey) - endps = []ingress.UpstreamServer{nginx.NewDefaultServer()} - } else { - upstream.Backends = append(upstream.Backends, endps...) - } - - return upstream -} - -// getUpstreamServers returns a list of Upstream and Server to be used in NGINX. -// An upstream can be used in multiple servers if the namespace, service name and port are the same -func (lbc *loadBalancerController) getUpstreamServers(ngxCfg config.Configuration, data []interface{}) ([]*ingress.Upstream, []*ingress.Server) { - upstreams := lbc.createUpstreams(ngxCfg, data) - servers := lbc.createServers(data, upstreams) - - for _, ingIf := range data { - ing := ingIf.(*extensions.Ingress) - - nginxAuth, err := auth.ParseAnnotations(lbc.client, ing, auth.DefAuthDirectory) - glog.V(3).Infof("nginx auth %v", nginxAuth) - if err != nil { - glog.V(3).Infof("error reading authentication in Ingress %v/%v: %v", ing.GetNamespace(), ing.GetName(), err) - } - - rl, err := ratelimit.ParseAnnotations(ing) - glog.V(3).Infof("nginx rate limit %v", rl) - if err != nil { - glog.V(3).Infof("error reading rate limit annotation in Ingress %v/%v: %v", ing.GetNamespace(), ing.GetName(), err) - } - - secUpstream, err := secureupstream.ParseAnnotations(ing) - if err != nil { - glog.V(3).Infof("error reading secure upstream in Ingress %v/%v: %v", ing.GetNamespace(), ing.GetName(), err) - } - - locRew, err := rewrite.ParseAnnotations(ngxCfg, ing) - if err != nil { - glog.V(3).Infof("error parsing rewrite annotations for Ingress rule %v/%v: %v", ing.GetNamespace(), ing.GetName(), err) - } - - wl, err := ipwhitelist.ParseAnnotations(ngxCfg.WhitelistSourceRange, ing) - glog.V(3).Infof("nginx white list %v", wl) - if err != nil { - 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) - } - - ra, err := authreq.ParseAnnotations(ing) - glog.V(3).Infof("nginx auth request %v", ra) - if err != nil { - glog.V(3).Infof("error reading auth request annotation in Ingress %v/%v: %v", ing.GetNamespace(), ing.GetName(), err) - } - - for _, rule := range ing.Spec.Rules { - host := rule.Host - if host == "" { - host = defServerName - } - server := servers[host] - if server == nil { - server = servers[defServerName] - } - - if rule.HTTP == nil && host != defServerName { - // no rules, host is not default server. - // check if Ingress rules contains Backend and replace default backend - defBackend := fmt.Sprintf("default-backend-%v-%v-%v", ing.GetNamespace(), ing.Spec.Backend.ServiceName, ing.Spec.Backend.ServicePort.String()) - ups := upstreams[defBackend] - for _, loc := range server.Locations { - loc.Upstream = *ups - } - continue - } - - for _, path := range rule.HTTP.Paths { - upsName := fmt.Sprintf("%v-%v-%v", ing.GetNamespace(), path.Backend.ServiceName, path.Backend.ServicePort.String()) - ups := upstreams[upsName] - - // we need to check if the upstream contains the default backend - if isDefaultUpstream(ups) && ing.Spec.Backend != nil { - defBackend := fmt.Sprintf("default-backend-%v-%v-%v", ing.GetNamespace(), ing.Spec.Backend.ServiceName, ing.Spec.Backend.ServicePort.String()) - if defUps, ok := upstreams[defBackend]; ok { - ups = defUps - } - } - - nginxPath := path.Path - // if there's no path defined we assume / - // in NGINX / == /* - if nginxPath == "" { - lbc.recorder.Eventf(ing, api.EventTypeWarning, "MAPPING", - "Ingress rule '%v/%v' contains no path definition. Assuming /", - ing.GetNamespace(), ing.GetName()) - nginxPath = rootLocation - } - - // Validate that there is no previous rule for the same host and path. - addLoc := true - for _, loc := range server.Locations { - if loc.Path == rootLocation && nginxPath == rootLocation && loc.IsDefBackend { - loc.Upstream = *ups - loc.Auth = *nginxAuth - loc.RateLimit = *rl - loc.Redirect = *locRew - loc.SecureUpstream = secUpstream - loc.Whitelist = *wl - loc.IsDefBackend = false - loc.Upstream = *ups - loc.EnableCORS = eCORS - loc.ExternalAuthURL = ra - - addLoc = false - continue - } - - if loc.Path == nginxPath { - lbc.recorder.Eventf(ing, api.EventTypeWarning, "MAPPING", - "Path '%v' already defined in another Ingress rule", nginxPath) - addLoc = false - break - } - } - - if addLoc { - server.Locations = append(server.Locations, &ingress.Location{ - Path: nginxPath, - Upstream: *ups, - Auth: *nginxAuth, - RateLimit: *rl, - Redirect: *locRew, - SecureUpstream: secUpstream, - Whitelist: *wl, - EnableCORS: eCORS, - ExternalAuthURL: ra, - }) - } - } - } - } - - // TODO: find a way to make this more readable - // The structs must be ordered to always generate the same file - // if the content does not change. - aUpstreams := make([]*ingress.Upstream, 0, len(upstreams)) - for _, value := range upstreams { - if len(value.Backends) == 0 { - glog.Warningf("upstream %v does not have any active endpoints. Using default backend", value.Name) - value.Backends = append(value.Backends, nginx.NewDefaultServer()) - } - sort.Sort(ingress.UpstreamServerByAddrPort(value.Backends)) - aUpstreams = append(aUpstreams, value) - } - sort.Sort(ingress.UpstreamByNameServers(aUpstreams)) - - aServers := make([]*ingress.Server, 0, len(servers)) - for _, value := range servers { - sort.Sort(ingress.LocationByPath(value.Locations)) - aServers = append(aServers, value) - } - sort.Sort(ingress.ServerByName(aServers)) - - return aUpstreams, aServers -} - -// createUpstreams creates the NGINX upstreams for each service referenced in -// Ingress rules. The servers inside the upstream are endpoints. -func (lbc *loadBalancerController) createUpstreams(ngxCfg config.Configuration, data []interface{}) map[string]*ingress.Upstream { - upstreams := make(map[string]*ingress.Upstream) - upstreams[defUpstreamName] = lbc.getDefaultUpstream() - - for _, ingIf := range data { - ing := ingIf.(*extensions.Ingress) - - hz := healthcheck.ParseAnnotations(ngxCfg, ing) - - var defBackend string - if ing.Spec.Backend != nil { - defBackend = fmt.Sprintf("default-backend-%v-%v-%v", ing.GetNamespace(), ing.Spec.Backend.ServiceName, ing.Spec.Backend.ServicePort.String()) - glog.V(3).Infof("creating upstream %v", defBackend) - upstreams[defBackend] = nginx.NewUpstream(defBackend) - - svcKey := fmt.Sprintf("%v/%v", ing.GetNamespace(), ing.Spec.Backend.ServiceName) - endps, err := lbc.getSvcEndpoints(svcKey, ing.Spec.Backend.ServicePort.String(), hz) - upstreams[defBackend].Backends = append(upstreams[defBackend].Backends, endps...) - if err != nil { - glog.Warningf("error creating upstream %v: %v", defBackend, err) - } - } - - for _, rule := range ing.Spec.Rules { - if rule.IngressRuleValue.HTTP == nil { - continue - } - - for _, path := range rule.HTTP.Paths { - name := fmt.Sprintf("%v-%v-%v", ing.GetNamespace(), path.Backend.ServiceName, path.Backend.ServicePort.String()) - if _, ok := upstreams[name]; ok { - continue - } - - glog.V(3).Infof("creating upstream %v", name) - upstreams[name] = nginx.NewUpstream(name) - - svcKey := fmt.Sprintf("%v/%v", ing.GetNamespace(), path.Backend.ServiceName) - endp, err := lbc.getSvcEndpoints(svcKey, path.Backend.ServicePort.String(), hz) - if err != nil { - glog.Warningf("error obtaining service endpoints: %v", err) - continue - } - upstreams[name].Backends = endp - } - } - } - - return upstreams -} - -func (lbc *loadBalancerController) getSvcEndpoints(svcKey, backendPort string, - hz *healthcheck.Upstream) ([]ingress.UpstreamServer, error) { - svcObj, svcExists, err := lbc.svcLister.Store.GetByKey(svcKey) - - var upstreams []ingress.UpstreamServer - if err != nil { - return upstreams, fmt.Errorf("error getting service %v from the cache: %v", svcKey, err) - } - - if !svcExists { - err = fmt.Errorf("service %v does not exists", svcKey) - return upstreams, err - } - - svc := svcObj.(*api.Service) - glog.V(3).Infof("obtaining port information for service %v", svcKey) - for _, servicePort := range svc.Spec.Ports { - // targetPort could be a string, use the name or the port (int) - if strconv.Itoa(int(servicePort.Port)) == backendPort || - servicePort.TargetPort.String() == backendPort || - servicePort.Name == backendPort { - - endps := lbc.getEndpoints(svc, servicePort.TargetPort, api.ProtocolTCP, hz) - if len(endps) == 0 { - glog.Warningf("service %v does not have any active endpoints", svcKey) - } - - upstreams = append(upstreams, endps...) - break - } - } - - return upstreams, nil -} - -func (lbc *loadBalancerController) createServers(data []interface{}, upstreams map[string]*ingress.Upstream) map[string]*ingress.Server { - servers := make(map[string]*ingress.Server) - - pems := lbc.getPemsFromIngress(data) - - var ngxCert ingress.SSLCert - var err error - - if lbc.defSSLCertificate == "" { - // use system certificated generated at image build time - cert, key := getFakeSSLCert() - ngxCert, err = lbc.nginx.AddOrUpdateCertAndKey("system-snake-oil-certificate", cert, key) - } else { - ngxCert, err = lbc.getPemCertificate(lbc.defSSLCertificate) - } - - locs := []*ingress.Location{} - locs = append(locs, &ingress.Location{ - Path: rootLocation, - IsDefBackend: true, - Upstream: *lbc.getDefaultUpstream(), - }) - servers[defServerName] = &ingress.Server{Name: defServerName, Locations: locs} - - if err == nil { - pems[defServerName] = ngxCert - servers[defServerName].SSL = true - servers[defServerName].SSLCertificate = ngxCert.PemFileName - servers[defServerName].SSLCertificateKey = ngxCert.PemFileName - servers[defServerName].SSLPemChecksum = ngxCert.PemSHA - } else { - glog.Warningf("unexpected error reading default SSL certificate: %v", err) - } - - for _, ingIf := range data { - ing := ingIf.(*extensions.Ingress) - - for _, rule := range ing.Spec.Rules { - host := rule.Host - if host == "" { - host = defServerName - } - - if _, ok := servers[host]; ok { - glog.V(3).Infof("rule %v/%v uses a host already defined. Skipping server creation", ing.GetNamespace(), ing.GetName()) - } else { - locs := []*ingress.Location{} - loc := &ingress.Location{ - Path: rootLocation, - IsDefBackend: true, - Upstream: *lbc.getDefaultUpstream(), - } - - if ing.Spec.Backend != nil { - defUpstream := fmt.Sprintf("default-backend-%v-%v-%v", ing.GetNamespace(), ing.Spec.Backend.ServiceName, ing.Spec.Backend.ServicePort.String()) - if backendUpstream, ok := upstreams[defUpstream]; ok { - if host == "" || host == defServerName { - lbc.recorder.Eventf(ing, api.EventTypeWarning, "MAPPING", "error: rules with Spec.Backend are allowed with hostnames") - } else { - loc.Upstream = *backendUpstream - } - } - } - - locs = append(locs, loc) - servers[host] = &ingress.Server{Name: host, Locations: locs} - } - - if ngxCert, ok := pems[host]; ok { - server := servers[host] - server.SSL = true - server.SSLCertificate = ngxCert.PemFileName - server.SSLCertificateKey = ngxCert.PemFileName - server.SSLPemChecksum = ngxCert.PemSHA - } - } - } - - return servers -} - -func (lbc *loadBalancerController) getPemsFromIngress(data []interface{}) map[string]ingress.SSLCert { - pems := make(map[string]ingress.SSLCert) - - for _, ingIf := range data { - ing := ingIf.(*extensions.Ingress) - for _, tls := range ing.Spec.TLS { - secretName := tls.SecretName - secretKey := fmt.Sprintf("%s/%s", ing.Namespace, secretName) - - ngxCert, err := lbc.getPemCertificate(secretKey) - if err != nil { - glog.Warningf("%v", err) - continue - } - - for _, host := range tls.Hosts { - if isHostValid(host, ngxCert.CN) { - pems[host] = ngxCert - } else { - glog.Warningf("SSL Certificate stored in secret %v is not valid for the host %v defined in the Ingress rule %v", secretName, host, ing.Name) - } - } - } - } - - return pems -} - -func (lbc *loadBalancerController) getPemCertificate(secretName string) (ingress.SSLCert, error) { - secretInterface, exists, err := lbc.secrLister.Store.GetByKey(secretName) - if err != nil { - return ingress.SSLCert{}, fmt.Errorf("Error retriveing secret %v: %v", secretName, err) - } - if !exists { - return ingress.SSLCert{}, fmt.Errorf("Secret %v does not exists", secretName) - } - - secret := secretInterface.(*api.Secret) - cert, ok := secret.Data[api.TLSCertKey] - if !ok { - return ingress.SSLCert{}, fmt.Errorf("Secret %v has no private key", secretName) - } - key, ok := secret.Data[api.TLSPrivateKeyKey] - if !ok { - return ingress.SSLCert{}, fmt.Errorf("Secret %v has no cert", secretName) - } - - nsSecName := strings.Replace(secretName, "/", "-", -1) - return lbc.nginx.AddOrUpdateCertAndKey(nsSecName, string(cert), string(key)) -} - -// check if secret is referenced in this controller's config -func (lbc *loadBalancerController) secrReferenced(namespace string, name string) bool { - for _, ingIf := range lbc.ingLister.Store.List() { - ing := ingIf.(*extensions.Ingress) - if ing.Namespace != namespace { - continue - } - for _, tls := range ing.Spec.TLS { - if tls.SecretName == name { - return true - } - } - } - return false -} - -// getEndpoints returns a list of : for a given service/target port combination. -func (lbc *loadBalancerController) getEndpoints( - s *api.Service, - servicePort intstr.IntOrString, - proto api.Protocol, - hz *healthcheck.Upstream) []ingress.UpstreamServer { - glog.V(3).Infof("getting endpoints for service %v/%v and port %v", s.Namespace, s.Name, servicePort.String()) - ep, err := lbc.endpLister.GetServiceEndpoints(s) - if err != nil { - glog.Warningf("unexpected error obtaining service endpoints: %v", err) - return []ingress.UpstreamServer{} - } - - upsServers := []ingress.UpstreamServer{} - - for _, ss := range ep.Subsets { - for _, epPort := range ss.Ports { - - if !reflect.DeepEqual(epPort.Protocol, proto) { - continue - } - - var targetPort int32 - switch servicePort.Type { - case intstr.Int: - if int(epPort.Port) == servicePort.IntValue() { - targetPort = epPort.Port - } - case intstr.String: - namedPorts := s.ObjectMeta.Annotations - val, ok := namedPortMapping(namedPorts).getPort(servicePort.StrVal) - if ok { - port, err := strconv.Atoi(val) - if err != nil { - glog.Warningf("%v is not valid as a port", val) - continue - } - - targetPort = int32(port) - } else { - newnp, err := lbc.checkSvcForUpdate(s) - if err != nil { - glog.Warningf("error mapping service ports: %v", err) - continue - } - val, ok := namedPortMapping(newnp).getPort(servicePort.StrVal) - if ok { - port, err := strconv.Atoi(val) - if err != nil { - glog.Warningf("%v is not valid as a port", val) - continue - } - - targetPort = int32(port) - } - } - } - - if targetPort == 0 { - continue - } - - for _, epAddress := range ss.Addresses { - ups := ingress.UpstreamServer{ - Address: epAddress.IP, - Port: fmt.Sprintf("%v", targetPort), - MaxFails: hz.MaxFails, - FailTimeout: hz.FailTimeout, - } - upsServers = append(upsServers, ups) - } - } - } - - glog.V(3).Infof("endpoints found: %v", upsServers) - return upsServers -} - -// Stop stops the loadbalancer controller. -func (lbc *loadBalancerController) Stop() error { - // Stop is invoked from the http endpoint. - lbc.stopLock.Lock() - defer lbc.stopLock.Unlock() - - // Only try draining the workqueue if we haven't already. - if !lbc.shutdown { - lbc.shutdown = true - close(lbc.stopCh) - - ings := lbc.ingLister.Store.List() - glog.Infof("removing IP address %v from ingress rules", lbc.podInfo.NodeIP) - lbc.removeFromIngress(ings) - - glog.Infof("Shutting down controller queues.") - lbc.syncQueue.shutdown() - lbc.ingQueue.shutdown() - - return nil - } - - return fmt.Errorf("shutdown already in progress") -} - -// removeFromIngress removes the IP address of the node where the Ingres -// controller is running before shutdown to avoid incorrect status -// information in Ingress rules -func (lbc *loadBalancerController) removeFromIngress(ings []interface{}) { - glog.Infof("updating %v Ingress rule/s", len(ings)) - for _, cur := range ings { - ing := cur.(*extensions.Ingress) - - ingClient := lbc.client.Extensions().Ingress(ing.Namespace) - currIng, err := ingClient.Get(ing.Name) - if err != nil { - glog.Errorf("unexpected error searching Ingress %v/%v: %v", ing.Namespace, ing.Name, err) - continue - } - - lbIPs := ing.Status.LoadBalancer.Ingress - if len(lbIPs) > 0 && lbc.isStatusIPDefined(lbIPs) { - glog.Infof("Updating loadbalancer %v/%v. Removing IP %v", ing.Namespace, ing.Name, lbc.podInfo.NodeIP) - - for idx, lbStatus := range currIng.Status.LoadBalancer.Ingress { - if lbStatus.IP == lbc.podInfo.NodeIP { - currIng.Status.LoadBalancer.Ingress = append(currIng.Status.LoadBalancer.Ingress[:idx], - currIng.Status.LoadBalancer.Ingress[idx+1:]...) - break - } - } - - if _, err := ingClient.UpdateStatus(currIng); err != nil { - lbc.recorder.Eventf(currIng, api.EventTypeWarning, "UPDATE", "error: %v", err) - continue - } - - lbc.recorder.Eventf(currIng, api.EventTypeNormal, "DELETE", "ip: %v", lbc.podInfo.NodeIP) - } - } -} - -// Run starts the loadbalancer controller. -func (lbc *loadBalancerController) Run() { - glog.Infof("starting NGINX loadbalancer controller") - go lbc.nginx.Start() - - go lbc.ingController.Run(lbc.stopCh) - go lbc.endpController.Run(lbc.stopCh) - go lbc.svcController.Run(lbc.stopCh) - go lbc.secrController.Run(lbc.stopCh) - go lbc.mapController.Run(lbc.stopCh) - - go lbc.syncQueue.run(time.Second, lbc.stopCh) - go lbc.ingQueue.run(time.Second, lbc.stopCh) - - <-lbc.stopCh -} - -func isDefaultUpstream(ups *ingress.Upstream) bool { - if ups == nil || len(ups.Backends) == 0 { - return false - } - - return ups.Backends[0].Address == "127.0.0.1" && - ups.Backends[0].Port == "8181" -} diff --git a/controllers/nginx/lua/vendor/lua-resty-http/lua-resty-http-0.07-0.rockspec b/controllers/nginx/lua/vendor/lua-resty-http/lua-resty-http-0.07-0.rockspec deleted file mode 100644 index d8e892281a..0000000000 --- a/controllers/nginx/lua/vendor/lua-resty-http/lua-resty-http-0.07-0.rockspec +++ /dev/null @@ -1,33 +0,0 @@ -package = "lua-resty-http" -version = "0.07-0" -source = { - url = "git://github.com/pintsized/lua-resty-http", - tag = "v0.07" -} -description = { - summary = "Lua HTTP client cosocket driver for OpenResty / ngx_lua.", - detailed = [[ - Features an HTTP 1.0 and 1.1 streaming interface to reading - bodies using coroutines, for predictable memory usage in Lua - land. Alternative simple interface for singleshot requests - without manual connection step. Supports chunked transfer - encoding, keepalive, pipelining, and trailers. Headers are - treated case insensitively. Probably production ready in most - cases, though not yet proven in the wild. - Recommended by the OpenResty maintainer as a long-term - replacement for internal requests through ngx.location.capture. - ]], - homepage = "https://github.com/pintsized/lua-resty-http", - license = "2-clause BSD", - maintainer = "James Hurst " -} -dependencies = { - "lua >= 5.1" -} -build = { - type = "builtin", - modules = { - ["resty.http"] = "lib/resty/http.lua", - ["resty.http_headers"] = "lib/resty/http_headers.lua" - } -} diff --git a/controllers/nginx/main.go b/controllers/nginx/main.go deleted file mode 100644 index 42d47c0e7d..0000000000 --- a/controllers/nginx/main.go +++ /dev/null @@ -1,192 +0,0 @@ -/* -Copyright 2015 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 main - -import ( - "flag" - "fmt" - "net/http" - "net/http/pprof" - "os" - "os/signal" - "syscall" - "time" - - "github.com/golang/glog" - "github.com/spf13/pflag" - - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/client/unversioned" - "k8s.io/kubernetes/pkg/healthz" - kubectl_util "k8s.io/kubernetes/pkg/kubectl/cmd/util" -) - -const ( - healthPort = 10254 -) - -var ( - // value overwritten during build. This can be used to resolve issues. - version = "0.8.3" - gitRepo = "https://github.com/kubernetes/contrib" - - flags = pflag.NewFlagSet("", pflag.ExitOnError) - - defaultSvc = flags.String("default-backend-service", "", - `Service used to serve a 404 page for the default backend. Takes the form - namespace/name. The controller uses the first node port of this Service for - the default backend.`) - - nxgConfigMap = flags.String("nginx-configmap", "", - `Name of the ConfigMap that containes the custom nginx configuration to use`) - - tcpConfigMapName = flags.String("tcp-services-configmap", "", - `Name of the ConfigMap that containes the definition of the TCP services to expose. - The key in the map indicates the external port to be used. The value is the name of the - service with the format namespace/serviceName and the port of the service could be a number of the - name of the port. - The ports 80 and 443 are not allowed as external ports. This ports are reserved for nginx`) - - udpConfigMapName = flags.String("udp-services-configmap", "", - `Name of the ConfigMap that containes the definition of the UDP services to expose. - The key in the map indicates the external port to be used. The value is the name of the - service with the format namespace/serviceName and the port of the service could be a number of the - name of the port.`) - - resyncPeriod = flags.Duration("sync-period", 30*time.Second, - `Relist and confirm cloud resources this often.`) - - watchNamespace = flags.String("watch-namespace", api.NamespaceAll, - `Namespace to watch for Ingress. Default is to watch all namespaces`) - - healthzPort = flags.Int("healthz-port", healthPort, "port for healthz endpoint.") - - profiling = flags.Bool("profiling", true, `Enable profiling via web interface host:port/debug/pprof/`) - - defSSLCertificate = flags.String("default-ssl-certificate", "", `Name of the secret that contains a SSL - certificate to be used as default for a HTTPS catch-all server`) - - defHealthzURL = flags.String("health-check-path", "/ingress-controller-healthz", `Defines the URL to - be used as health check inside in the default server in NGINX.`) -) - -func main() { - flags.AddGoFlagSet(flag.CommandLine) - flags.Parse(os.Args) - clientConfig := kubectl_util.DefaultClientConfig(flags) - - glog.Infof("Using build: %v - %v", gitRepo, version) - - if *defaultSvc == "" { - glog.Fatalf("Please specify --default-backend-service") - } - - kubeClient, err := unversioned.NewInCluster() - if err != nil { - config, err := clientConfig.ClientConfig() - if err != nil { - glog.Fatalf("error configuring the client: %v", err) - } - kubeClient, err = unversioned.New(config) - if err != nil { - glog.Fatalf("failed to create client: %v", err) - } - } - - runtimePodInfo, err := getPodDetails(kubeClient) - if err != nil { - runtimePodInfo = &podInfo{NodeIP: "127.0.0.1"} - glog.Warningf("unexpected error getting runtime information: %v", err) - } - if err := isValidService(kubeClient, *defaultSvc); err != nil { - glog.Fatalf("no service with name %v found: %v", *defaultSvc, err) - } - glog.Infof("Validated %v as the default backend", *defaultSvc) - - if *nxgConfigMap != "" { - _, _, err = parseNsName(*nxgConfigMap) - if err != nil { - glog.Fatalf("configmap error: %v", err) - } - } - - lbc, err := newLoadBalancerController(kubeClient, *resyncPeriod, - *defaultSvc, *watchNamespace, *nxgConfigMap, *tcpConfigMapName, - *udpConfigMapName, *defSSLCertificate, *defHealthzURL, runtimePodInfo) - if err != nil { - glog.Fatalf("%v", err) - } - - go registerHandlers(lbc) - go handleSigterm(lbc) - - lbc.Run() - - for { - glog.Infof("Handled quit, awaiting pod deletion") - time.Sleep(30 * time.Second) - } -} - -// podInfo contains runtime information about the pod -type podInfo struct { - PodName string - PodNamespace string - NodeIP string -} - -func registerHandlers(lbc *loadBalancerController) { - mux := http.NewServeMux() - healthz.InstallHandler(mux, lbc.nginx) - - mux.HandleFunc("/build", func(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, "build: %v - %v", gitRepo, version) - }) - - mux.HandleFunc("/stop", func(w http.ResponseWriter, r *http.Request) { - lbc.Stop() - }) - - if *profiling { - mux.HandleFunc("/debug/pprof/", pprof.Index) - mux.HandleFunc("/debug/pprof/profile", pprof.Profile) - mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol) - } - - server := &http.Server{ - Addr: fmt.Sprintf(":%v", *healthzPort), - Handler: mux, - } - glog.Fatal(server.ListenAndServe()) -} - -func handleSigterm(lbc *loadBalancerController) { - signalChan := make(chan os.Signal, 1) - signal.Notify(signalChan, syscall.SIGTERM) - <-signalChan - glog.Infof("Received SIGTERM, shutting down") - - exitCode := 0 - if err := lbc.Stop(); err != nil { - glog.Infof("Error during shutdown %v", err) - exitCode = 1 - } - - glog.Infof("Exiting with %v", exitCode) - os.Exit(exitCode) -} diff --git a/controllers/nginx/nginx/command.go b/controllers/nginx/nginx/command.go deleted file mode 100644 index 38fc473236..0000000000 --- a/controllers/nginx/nginx/command.go +++ /dev/null @@ -1,138 +0,0 @@ -/* -Copyright 2015 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 nginx - -import ( - "fmt" - "io/ioutil" - "net/http" - "os" - "os/exec" - - "github.com/golang/glog" - - "k8s.io/kubernetes/pkg/healthz" - - "k8s.io/contrib/ingress/controllers/nginx/nginx/config" - "k8s.io/contrib/ingress/controllers/nginx/nginx/ingress" -) - -// Start starts a nginx (master process) and waits. If the process ends -// we need to kill the controller process and return the reason. -func (ngx *Manager) Start() { - glog.Info("Starting NGINX process...") - cmd := exec.Command("nginx") - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - if err := cmd.Start(); err != nil { - glog.Errorf("nginx error: %v", err) - } - - if err := cmd.Wait(); err != nil { - glog.Errorf("nginx error: %v", err) - } -} - -// CheckAndReload verify if the nginx configuration changed and sends a reload -// -// the master process receives the signal to reload configuration, it checks -// the syntax validity of the new configuration file and tries to apply the -// configuration provided in it. If this is a success, the master process starts -// new worker processes and sends messages to old worker processes, requesting them -// to shut down. Otherwise, the master process rolls back the changes and continues -// to work with the old configuration. Old worker processes, receiving a command to -// shut down, stop accepting new connections and continue to service current requests -// until all such requests are serviced. After that, the old worker processes exit. -// http://nginx.org/en/docs/beginners_guide.html#control -func (ngx *Manager) CheckAndReload(cfg config.Configuration, ingressCfg ingress.Configuration) error { - ngx.reloadRateLimiter.Accept() - - ngx.reloadLock.Lock() - defer ngx.reloadLock.Unlock() - - newCfg, err := ngx.template.Write(cfg, ingressCfg, ngx.testTemplate) - if err != nil { - return fmt.Errorf("failed to write new nginx configuration. Avoiding reload: %v", err) - } - - changed, err := ngx.needsReload(newCfg) - if err != nil { - return err - } - - if changed { - if err := ngx.shellOut("nginx -s reload"); err != nil { - return fmt.Errorf("error reloading nginx: %v", err) - } - - glog.Info("change in configuration detected. Reloading...") - } - - return nil -} - -// shellOut executes a command and returns its combined standard output and standard -// error in case of an error in the execution -func (ngx *Manager) shellOut(cmd string) error { - out, err := exec.Command("sh", "-c", cmd).CombinedOutput() - if err != nil { - glog.Errorf("failed to execute %v: %v", cmd, string(out)) - return err - } - - return nil -} - -// check to verify Manager implements HealthzChecker interface -var _ healthz.HealthzChecker = Manager{} - -// Name returns the healthcheck name -func (ngx Manager) Name() string { - return "NGINX" -} - -// Check returns if the nginx healthz endpoint is returning ok (status code 200) -func (ngx Manager) Check(_ *http.Request) error { - res, err := http.Get("http://127.0.0.1:18080/healthz") - if err != nil { - return err - } - defer res.Body.Close() - - if res.StatusCode != 200 { - return fmt.Errorf("NGINX is unhealthy") - } - - return nil -} - -// testTemplate checks if the NGINX configuration inside the byte array is valid -// running the command "nginx -t" using a temporal file. -func (ngx Manager) testTemplate(cfg []byte) error { - tmpfile, err := ioutil.TempFile("", "nginx-cfg") - if err != nil { - return err - } - defer tmpfile.Close() - ioutil.WriteFile(tmpfile.Name(), cfg, 0644) - if err := ngx.shellOut(fmt.Sprintf("nginx -t -c %v", tmpfile.Name())); err != nil { - return fmt.Errorf("invalid nginx configuration: %v", err) - } - // in case of error do not remove temporal file - defer os.Remove(tmpfile.Name()) - return nil -} diff --git a/controllers/nginx/nginx/ingress/nginx.go b/controllers/nginx/nginx/ingress/nginx.go deleted file mode 100644 index 5dfd7dbff9..0000000000 --- a/controllers/nginx/nginx/ingress/nginx.go +++ /dev/null @@ -1,130 +0,0 @@ -/* -Copyright 2015 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 ingress - -import ( - "k8s.io/contrib/ingress/controllers/nginx/nginx/auth" - "k8s.io/contrib/ingress/controllers/nginx/nginx/authreq" - "k8s.io/contrib/ingress/controllers/nginx/nginx/ipwhitelist" - "k8s.io/contrib/ingress/controllers/nginx/nginx/ratelimit" - "k8s.io/contrib/ingress/controllers/nginx/nginx/rewrite" -) - -// Configuration describes an NGINX configuration -type Configuration struct { - Upstreams []*Upstream - Servers []*Server - TCPUpstreams []*Location - UDPUpstreams []*Location -} - -// Upstream describes an NGINX upstream -type Upstream struct { - Name string - Backends []UpstreamServer - Secure bool -} - -// UpstreamByNameServers sorts upstreams by name -type UpstreamByNameServers []*Upstream - -func (c UpstreamByNameServers) Len() int { return len(c) } -func (c UpstreamByNameServers) Swap(i, j int) { c[i], c[j] = c[j], c[i] } -func (c UpstreamByNameServers) Less(i, j int) bool { - return c[i].Name < c[j].Name -} - -// UpstreamServer describes a server in an NGINX upstream -type UpstreamServer struct { - Address string - Port string - MaxFails int - FailTimeout int -} - -// UpstreamServerByAddrPort sorts upstream servers by address and port -type UpstreamServerByAddrPort []UpstreamServer - -func (c UpstreamServerByAddrPort) Len() int { return len(c) } -func (c UpstreamServerByAddrPort) Swap(i, j int) { c[i], c[j] = c[j], c[i] } -func (c UpstreamServerByAddrPort) Less(i, j int) bool { - iName := c[i].Address - jName := c[j].Address - if iName != jName { - return iName < jName - } - - iU := c[i].Port - jU := c[j].Port - return iU < jU -} - -// Server describes an NGINX server -type Server struct { - Name string - Locations []*Location - SSL bool - SSLCertificate string - SSLCertificateKey string - SSLPemChecksum string -} - -// ServerByName sorts server by name -type ServerByName []*Server - -func (c ServerByName) Len() int { return len(c) } -func (c ServerByName) Swap(i, j int) { c[i], c[j] = c[j], c[i] } -func (c ServerByName) Less(i, j int) bool { - return c[i].Name < c[j].Name -} - -// Location describes an NGINX location -type Location struct { - Path string - IsDefBackend bool - Upstream Upstream - Auth auth.Nginx - RateLimit ratelimit.RateLimit - Redirect rewrite.Redirect - SecureUpstream bool - Whitelist ipwhitelist.SourceRange - EnableCORS bool - ExternalAuthURL authreq.Auth -} - -// LocationByPath sorts location by path -// Location / is the last one -type LocationByPath []*Location - -func (c LocationByPath) Len() int { return len(c) } -func (c LocationByPath) Swap(i, j int) { c[i], c[j] = c[j], c[i] } -func (c LocationByPath) Less(i, j int) bool { - return c[i].Path > c[j].Path -} - -// SSLCert describes a SSL certificate to be used in NGINX -type SSLCert struct { - CertFileName string - KeyFileName string - // PemFileName contains the path to the file with the certificate and key concatenated - PemFileName string - // PemSHA contains the sha1 of the pem file. - // This is used to detect changes in the secret that contains the certificates - PemSHA string - // CN contains all the common names defined in the SSL certificate - CN []string -} diff --git a/controllers/nginx/nginx/main.go b/controllers/nginx/nginx/main.go deleted file mode 100644 index 944181b1dc..0000000000 --- a/controllers/nginx/nginx/main.go +++ /dev/null @@ -1,118 +0,0 @@ -/* -Copyright 2015 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 nginx - -import ( - "os" - "strings" - "sync" - - "github.com/golang/glog" - - client "k8s.io/kubernetes/pkg/client/unversioned" - "k8s.io/kubernetes/pkg/util/flowcontrol" - - "k8s.io/contrib/ingress/controllers/nginx/nginx/config" - "k8s.io/contrib/ingress/controllers/nginx/nginx/ingress" - ngx_template "k8s.io/contrib/ingress/controllers/nginx/nginx/template" -) - -var ( - tmplPath = "/etc/nginx/template/nginx.tmpl" -) - -// Manager ... -type Manager struct { - ConfigFile string - - defCfg config.Configuration - - defResolver string - - sslDHParam string - - reloadRateLimiter flowcontrol.RateLimiter - - // template loaded ready to be used to generate the nginx configuration file - template *ngx_template.Template - - reloadLock *sync.Mutex -} - -// NewDefaultServer return an UpstreamServer to be use as default server that returns 503. -func NewDefaultServer() ingress.UpstreamServer { - return ingress.UpstreamServer{Address: "127.0.0.1", Port: "8181"} -} - -// NewUpstream creates an upstream without servers. -func NewUpstream(name string) *ingress.Upstream { - return &ingress.Upstream{ - Name: name, - Backends: []ingress.UpstreamServer{}, - } -} - -// NewManager ... -func NewManager(kubeClient *client.Client) *Manager { - ngx := &Manager{ - ConfigFile: "/etc/nginx/nginx.conf", - defCfg: config.NewDefault(), - reloadLock: &sync.Mutex{}, - reloadRateLimiter: flowcontrol.NewTokenBucketRateLimiter(0.1, 1), - } - - res, err := getDNSServers() - if err != nil { - glog.Warningf("error reading nameservers: %v", err) - } - ngx.defResolver = strings.Join(res, " ") - - ngx.createCertsDir(config.SSLDirectory) - - ngx.sslDHParam = ngx.SearchDHParamFile(config.SSLDirectory) - - var onChange func() - onChange = func() { - template, err := ngx_template.NewTemplate(tmplPath, onChange) - if err != nil { - glog.Warningf("invalid NGINX template: %v", err) - return - } - - ngx.template.Close() - ngx.template = template - glog.Info("new NGINX template loaded") - } - - template, err := ngx_template.NewTemplate(tmplPath, onChange) - if err != nil { - glog.Fatalf("invalid NGINX template: %v", err) - } - - ngx.template = template - return ngx -} - -func (nginx *Manager) createCertsDir(base string) { - if err := os.Mkdir(base, os.ModeDir); err != nil { - if os.IsExist(err) { - glog.Infof("%v already exists", err) - return - } - glog.Fatalf("Couldn't create directory %v: %v", base, err) - } -} diff --git a/controllers/nginx/nginx/ssl.go b/controllers/nginx/nginx/ssl.go deleted file mode 100644 index 25338f3aab..0000000000 --- a/controllers/nginx/nginx/ssl.go +++ /dev/null @@ -1,135 +0,0 @@ -/* -Copyright 2015 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 nginx - -import ( - "crypto/sha1" - "crypto/x509" - "encoding/hex" - "encoding/pem" - "fmt" - "io/ioutil" - "os" - - "github.com/golang/glog" - - "k8s.io/contrib/ingress/controllers/nginx/nginx/config" - "k8s.io/contrib/ingress/controllers/nginx/nginx/ingress" -) - -// AddOrUpdateCertAndKey creates a .pem file wth the cert and the key with the specified name -func (nginx *Manager) AddOrUpdateCertAndKey(name string, cert string, key string) (ingress.SSLCert, error) { - temporaryPemFileName := fmt.Sprintf("%v.pem", name) - pemFileName := fmt.Sprintf("%v/%v.pem", config.SSLDirectory, name) - - temporaryPemFile, err := ioutil.TempFile("", temporaryPemFileName) - if err != nil { - return ingress.SSLCert{}, fmt.Errorf("Couldn't create temp pem file %v: %v", temporaryPemFile.Name(), err) - } - - _, err = temporaryPemFile.WriteString(fmt.Sprintf("%v\n%v", cert, key)) - if err != nil { - return ingress.SSLCert{}, fmt.Errorf("Couldn't write to pem file %v: %v", temporaryPemFile.Name(), err) - } - - err = temporaryPemFile.Close() - if err != nil { - return ingress.SSLCert{}, fmt.Errorf("Couldn't close temp pem file %v: %v", temporaryPemFile.Name(), err) - } - - cn, err := nginx.commonNames(temporaryPemFile.Name()) - if err != nil { - os.Remove(temporaryPemFile.Name()) - return ingress.SSLCert{}, err - } - - err = os.Rename(temporaryPemFile.Name(), pemFileName) - if err != nil { - os.Remove(temporaryPemFile.Name()) - return ingress.SSLCert{}, fmt.Errorf("Couldn't move temp pem file %v to destination %v: %v", temporaryPemFile.Name(), pemFileName, err) - } - - return ingress.SSLCert{ - CertFileName: cert, - KeyFileName: key, - PemFileName: pemFileName, - PemSHA: nginx.pemSHA1(pemFileName), - CN: cn, - }, nil -} - -// commonNames checks if the certificate and key file are valid -// returning the result of the validation and the list of hostnames -// contained in the common name/s -func (nginx *Manager) commonNames(pemFileName string) ([]string, error) { - pemCerts, err := ioutil.ReadFile(pemFileName) - if err != nil { - return []string{}, err - } - - block, _ := pem.Decode(pemCerts) - if block == nil { - return []string{}, fmt.Errorf("No valid PEM formatted block found") - } - - cert, err := x509.ParseCertificate(block.Bytes) - if err != nil { - return []string{}, err - } - - cn := []string{cert.Subject.CommonName} - if len(cert.DNSNames) > 0 { - cn = append(cn, cert.DNSNames...) - } - - glog.V(3).Infof("found %v common names: %v\n", cn, len(cn)) - return cn, nil -} - -// SearchDHParamFile iterates all the secrets mounted inside the /etc/nginx-ssl directory -// in order to find a file with the name dhparam.pem. If such file exists it will -// returns the path. If not it just returns an empty string -func (nginx *Manager) SearchDHParamFile(baseDir string) string { - files, _ := ioutil.ReadDir(baseDir) - for _, file := range files { - if !file.IsDir() { - continue - } - - dhPath := fmt.Sprintf("%v/%v/dhparam.pem", baseDir, file.Name()) - if _, err := os.Stat(dhPath); err == nil { - glog.Infof("using file '%v' for parameter ssl_dhparam", dhPath) - return dhPath - } - } - - glog.Warning("no file dhparam.pem found in secrets") - return "" -} - -// pemSHA1 returns the SHA1 of a pem file. This is used to -// reload NGINX in case a secret with a SSL certificate changed. -func (nginx *Manager) pemSHA1(filename string) string { - hasher := sha1.New() - s, err := ioutil.ReadFile(filename) - if err != nil { - return "" - } - - hasher.Write(s) - return hex.EncodeToString(hasher.Sum(nil)) -} diff --git a/controllers/nginx/nginx/utils.go b/controllers/nginx/nginx/utils.go deleted file mode 100644 index 40a6dffd60..0000000000 --- a/controllers/nginx/nginx/utils.go +++ /dev/null @@ -1,224 +0,0 @@ -/* -Copyright 2015 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 nginx - -import ( - "bytes" - "io/ioutil" - "os" - "os/exec" - "reflect" - "strconv" - "strings" - - "github.com/golang/glog" - "github.com/mitchellh/mapstructure" - "k8s.io/kubernetes/pkg/api" - - "k8s.io/contrib/ingress/controllers/nginx/nginx/config" -) - -const ( - customHTTPErrors = "custom-http-errors" - skipAccessLogUrls = "skip-access-log-urls" -) - -// getDNSServers returns the list of nameservers located in the file /etc/resolv.conf -func getDNSServers() ([]string, error) { - var nameservers []string - file, err := ioutil.ReadFile("/etc/resolv.conf") - if err != nil { - return nameservers, err - } - - // Lines of the form "nameserver 1.2.3.4" accumulate. - lines := strings.Split(string(file), "\n") - for l := range lines { - trimmed := strings.TrimSpace(lines[l]) - if strings.HasPrefix(trimmed, "#") { - continue - } - fields := strings.Fields(trimmed) - if len(fields) == 0 { - continue - } - if fields[0] == "nameserver" { - nameservers = append(nameservers, fields[1:]...) - } - } - - glog.V(3).Infof("nameservers to use: %v", nameservers) - return nameservers, nil -} - -// getConfigKeyToStructKeyMap returns a map with the ConfigMapKey as key and the StructName as value. -func getConfigKeyToStructKeyMap() map[string]string { - keyMap := map[string]string{} - n := &config.Configuration{} - val := reflect.Indirect(reflect.ValueOf(n)) - for i := 0; i < val.Type().NumField(); i++ { - fieldSt := val.Type().Field(i) - configMapKey := strings.Split(fieldSt.Tag.Get("structs"), ",")[0] - structKey := fieldSt.Name - keyMap[configMapKey] = structKey - } - return keyMap -} - -// ReadConfig obtains the configuration defined by the user merged with the defaults. -func (ngx *Manager) ReadConfig(conf *api.ConfigMap) config.Configuration { - if len(conf.Data) == 0 { - return config.NewDefault() - } - - cfgCM := config.Configuration{} - cfgDefault := config.NewDefault() - - metadata := &mapstructure.Metadata{} - - decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ - TagName: "structs", - Result: &cfgCM, - WeaklyTypedInput: true, - Metadata: metadata, - }) - - cErrors := make([]int, 0) - if val, ok := conf.Data[customHTTPErrors]; ok { - delete(conf.Data, customHTTPErrors) - for _, i := range strings.Split(val, ",") { - j, err := strconv.Atoi(i) - if err != nil { - glog.Warningf("%v is not a valid http code: %v", i, err) - } else { - cErrors = append(cErrors, j) - } - } - } - - cSkipUrls := make([]string, 0) - if val, ok := conf.Data[skipAccessLogUrls]; ok { - delete(conf.Data, skipAccessLogUrls) - cSkipUrls = strings.Split(val, ",") - } - - err = decoder.Decode(conf.Data) - if err != nil { - glog.Infof("%v", err) - } - - keyMap := getConfigKeyToStructKeyMap() - - valCM := reflect.Indirect(reflect.ValueOf(cfgCM)) - - for _, key := range metadata.Keys { - fieldName, ok := keyMap[key] - if !ok { - continue - } - - valDefault := reflect.ValueOf(&cfgDefault).Elem().FieldByName(fieldName) - - fieldCM := valCM.FieldByName(fieldName) - - if valDefault.IsValid() { - valDefault.Set(fieldCM) - } - } - - cfgDefault.CustomHTTPErrors = ngx.filterErrors(cErrors) - cfgDefault.SkipAccessLogURLs = cSkipUrls - // no custom resolver means use the system resolver - if cfgDefault.Resolver == "" { - cfgDefault.Resolver = ngx.defResolver - } - return cfgDefault -} - -func (ngx *Manager) filterErrors(errCodes []int) []int { - fa := make([]int, 0) - for _, errCode := range errCodes { - if errCode > 299 && errCode < 600 { - fa = append(fa, errCode) - } else { - glog.Warningf("error code %v is not valid for custom error pages", errCode) - } - } - - return fa -} - -func (ngx *Manager) needsReload(data []byte) (bool, error) { - filename := ngx.ConfigFile - in, err := os.Open(filename) - if err != nil { - return false, err - } - - src, err := ioutil.ReadAll(in) - in.Close() - if err != nil { - return false, err - } - - if !bytes.Equal(src, data) { - err = ioutil.WriteFile(filename, data, 0644) - if err != nil { - return false, err - } - - dData, err := diff(src, data) - if err != nil { - glog.Errorf("error computing diff: %s", err) - return true, nil - } - - if glog.V(2) { - glog.Infof("NGINX configuration diff a/%s b/%s\n", filename, filename) - glog.Infof("%v", string(dData)) - } - - return len(dData) > 0, nil - } - - return false, nil -} - -func diff(b1, b2 []byte) (data []byte, err error) { - f1, err := ioutil.TempFile("", "") - if err != nil { - return - } - defer os.Remove(f1.Name()) - defer f1.Close() - - f2, err := ioutil.TempFile("", "") - if err != nil { - return - } - defer os.Remove(f2.Name()) - defer f2.Close() - - f1.Write(b1) - f2.Write(b2) - - data, err = exec.Command("diff", "-u", f1.Name(), f2.Name()).CombinedOutput() - if len(data) > 0 { - err = nil - } - return -} diff --git a/controllers/nginx/nginx/utils_test.go b/controllers/nginx/nginx/utils_test.go deleted file mode 100644 index e9c37edd0b..0000000000 --- a/controllers/nginx/nginx/utils_test.go +++ /dev/null @@ -1,101 +0,0 @@ -/* -Copyright 2015 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 nginx - -import ( - "testing" - - "k8s.io/kubernetes/pkg/api" - - "k8s.io/contrib/ingress/controllers/nginx/nginx/config" -) - -func getConfigNginxBool(data map[string]string) config.Configuration { - manager := &Manager{} - configMap := &api.ConfigMap{ - Data: data, - } - return manager.ReadConfig(configMap) -} - -func TestManagerReadConfigBoolFalse(t *testing.T) { - configNginx := getConfigNginxBool(map[string]string{ - "hsts-include-subdomains": "false", - "use-proxy-protocol": "false", - }) - if configNginx.HSTSIncludeSubdomains { - t.Error("Failed to config boolean value (default true) to false") - } - if configNginx.UseProxyProtocol { - t.Error("Failed to config boolean value (default false) to false") - } -} - -func TestManagerReadConfigBoolTrue(t *testing.T) { - configNginx := getConfigNginxBool(map[string]string{ - "hsts-include-subdomains": "true", - "use-proxy-protocol": "true", - }) - if !configNginx.HSTSIncludeSubdomains { - t.Error("Failed to config boolean value (default true) to true") - } - if !configNginx.UseProxyProtocol { - t.Error("Failed to config boolean value (default false) to true") - } -} - -func TestManagerReadConfigBoolNothing(t *testing.T) { - configNginx := getConfigNginxBool(map[string]string{ - "invaild-key": "true", - }) - if !configNginx.HSTSIncludeSubdomains { - t.Error("Failed to get default boolean value true") - } - if configNginx.UseProxyProtocol { - t.Error("Failed to get default boolean value false") - } -} - -func TestManagerReadConfigStringSet(t *testing.T) { - configNginx := getConfigNginxBool(map[string]string{ - "ssl-protocols": "TLSv1.2", - }) - exp := "TLSv1.2" - if configNginx.SSLProtocols != exp { - t.Errorf("Failed to set string value true actual='%s' expected='%s'", configNginx.SSLProtocols, exp) - } -} - -func TestManagerReadConfigStringNothing(t *testing.T) { - configNginx := getConfigNginxBool(map[string]string{ - "not-existing": "TLSv1.2", - }) - exp := "10m" - if configNginx.SSLSessionTimeout != exp { - t.Errorf("Failed to set string value true actual='%s' expected='%s'", configNginx.SSLSessionTimeout, exp) - } -} - -func TestGetDNSServers(t *testing.T) { - s, err := getDNSServers() - if err != nil { - t.Fatalf("unexpected error reading /etc/resolv.conf file: %v", err) - } - if len(s) < 1 { - t.Error("expected at least 1 nameserver in /etc/resolv.conf") - } -} diff --git a/controllers/nginx/pkg/cmd/controller/main.go b/controllers/nginx/pkg/cmd/controller/main.go new file mode 100644 index 0000000000..4d7fc57566 --- /dev/null +++ b/controllers/nginx/pkg/cmd/controller/main.go @@ -0,0 +1,60 @@ +/* +Copyright 2015 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 main + +import ( + "os" + "os/signal" + "syscall" + "time" + + "github.com/golang/glog" + + "k8s.io/ingress/core/pkg/ingress/controller" +) + +func main() { + // start a new nginx controller + ngx := newNGINXController() + // create a custom Ingress controller using NGINX as backend + ic := controller.NewIngressController(ngx) + go handleSigterm(ic) + // start the controller + ic.Start() + // wait + glog.Infof("shutting down Ingress controller...") + for { + glog.Infof("Handled quit, awaiting pod deletion") + time.Sleep(30 * time.Second) + } +} + +func handleSigterm(ic controller.Interface) { + signalChan := make(chan os.Signal, 1) + signal.Notify(signalChan, syscall.SIGTERM) + <-signalChan + glog.Infof("Received SIGTERM, shutting down") + + exitCode := 0 + if err := ic.Stop(); err != nil { + glog.Infof("Error during shutdown %v", err) + exitCode = 1 + } + + glog.Infof("Exiting with %v", exitCode) + os.Exit(exitCode) +} diff --git a/controllers/nginx/pkg/cmd/controller/nginx.go b/controllers/nginx/pkg/cmd/controller/nginx.go new file mode 100644 index 0000000000..a42360b83e --- /dev/null +++ b/controllers/nginx/pkg/cmd/controller/nginx.go @@ -0,0 +1,266 @@ +/* +Copyright 2015 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 main + +import ( + "bytes" + "fmt" + "io/ioutil" + "os" + "os/exec" + + "github.com/golang/glog" + + "k8s.io/ingress/core/pkg/ingress" + "k8s.io/ingress/core/pkg/ingress/defaults" + + "k8s.io/ingress/controllers/nginx/pkg/config" + ngx_template "k8s.io/ingress/controllers/nginx/pkg/template" + "k8s.io/ingress/controllers/nginx/pkg/version" + + "k8s.io/kubernetes/pkg/api" +) + +var ( + tmplPath = "/etc/nginx/template/nginx.tmpl" + cfgPath = "/etc/nginx/nginx.conf" + binary = "/usr/sbin/nginx" +) + +// newNGINXController creates a new NGINX Ingress controller. +// If the environment variable NGINX_BINARY exists it will be used +// as source for nginx commands +func newNGINXController() ingress.Controller { + ngx := os.Getenv("NGINX_BINARY") + if ngx == "" { + ngx = binary + } + n := NGINXController{binary: ngx} + + var onChange func() + onChange = func() { + template, err := ngx_template.NewTemplate(tmplPath, onChange) + if err != nil { + // this error is different from the rest because it must be clear why nginx is not working + glog.Errorf(` +------------------------------------------------------------------------------- +Error loading new template : %v +------------------------------------------------------------------------------- +`, err) + return + } + + n.t.Close() + n.t = template + glog.Info("new NGINX template loaded") + } + + ngxTpl, err := ngx_template.NewTemplate(tmplPath, onChange) + if err != nil { + glog.Fatalf("invalid NGINX template: %v", err) + } + + n.t = ngxTpl + return n +} + +// NGINXController ... +type NGINXController struct { + t *ngx_template.Template + + binary string +} + +// Start ... +func (n NGINXController) Start() { + glog.Info("starting NGINX process...") + cmd := exec.Command(n.binary, "-c", cfgPath) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Start(); err != nil { + glog.Fatalf("nginx error: %v", err) + } + if err := cmd.Wait(); err != nil { + glog.Errorf("nginx error: %v", err) + } +} + +// Stop ... +func (n NGINXController) Stop() error { + n.t.Close() + return exec.Command(n.binary, "-s", "stop").Run() +} + +// Restart ... +func (n NGINXController) Restart(data []byte) ([]byte, error) { + err := ioutil.WriteFile(cfgPath, data, 0644) + if err != nil { + return nil, err + } + + return exec.Command(n.binary, "-s", "reload").CombinedOutput() +} + +// Test checks is a file contains a valid NGINX configuration +func (n NGINXController) Test(file string) *exec.Cmd { + return exec.Command(n.binary, "-t", "-c", file) +} + +// UpstreamDefaults returns the nginx defaults +func (n NGINXController) UpstreamDefaults() defaults.Backend { + d := config.NewDefault() + return d.Backend +} + +// IsReloadRequired check if the new configuration file is different +// from the current one. +func (n NGINXController) IsReloadRequired(data []byte) bool { + in, err := os.Open(cfgPath) + if err != nil { + return false + } + src, err := ioutil.ReadAll(in) + in.Close() + if err != nil { + return false + } + + if !bytes.Equal(src, data) { + tmpfile, err := ioutil.TempFile("", "nginx-cfg-diff") + if err != nil { + glog.Errorf("error creating temporal file: %s", err) + return false + } + defer tmpfile.Close() + err = ioutil.WriteFile(tmpfile.Name(), data, 0644) + if err != nil { + return false + } + + diffOutput, err := diff(src, data) + if err != nil { + glog.Errorf("error computing diff: %s", err) + return true + } + + if glog.V(2) { + glog.Infof("NGINX configuration diff\n") + glog.Infof("%v", string(diffOutput)) + } + return len(diffOutput) > 0 + } + return false +} + +// Info return build information +func (n NGINXController) Info() string { + return fmt.Sprintf("build version %v from repo %v commit %v", version.RELEASE, version.REPO, version.COMMIT) +} + +// testTemplate checks if the NGINX configuration inside the byte array is valid +// running the command "nginx -t" using a temporal file. +func (n NGINXController) testTemplate(cfg []byte) error { + tmpfile, err := ioutil.TempFile("", "nginx-cfg") + if err != nil { + return err + } + defer tmpfile.Close() + ioutil.WriteFile(tmpfile.Name(), cfg, 0644) + out, err := n.Test(tmpfile.Name()).CombinedOutput() + if err != nil { + // this error is different from the rest because it must be clear why nginx is not working + return fmt.Errorf(` +------------------------------------------------------------------------------- +Error: %v +%v +------------------------------------------------------------------------------- +`, err, string(out)) + } + + os.Remove(tmpfile.Name()) + return nil +} + +// 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. +// +// convert configmap to custom configuration object (different in each implementation) +// write the custom template (the complexity depends on the implementation) +// write the configuration file +// returning nill implies the backend will be reloaded. +// if an error is returned means requeue the update +func (n NGINXController) OnUpdate(cmap *api.ConfigMap, ingressCfg ingress.Configuration) ([]byte, error) { + var longestName int + var serverNames int + for _, srv := range ingressCfg.Servers { + serverNames += len([]byte(srv.Name)) + if longestName < len(srv.Name) { + longestName = len(srv.Name) + } + } + + cfg := ngx_template.ReadConfig(cmap) + + // NGINX cannot resize the has tables used to store server names. + // For this reason we check if the defined size defined is correct + // for the FQDN defined in the ingress rules adjusting the value + // if is required. + // https://trac.nginx.org/nginx/ticket/352 + // https://trac.nginx.org/nginx/ticket/631 + nameHashBucketSize := nextPowerOf2(longestName) + if nameHashBucketSize > cfg.ServerNameHashBucketSize { + glog.V(3).Infof("adjusting ServerNameHashBucketSize variable from %v to %v", + cfg.ServerNameHashBucketSize, nameHashBucketSize) + cfg.ServerNameHashBucketSize = nameHashBucketSize + } + serverNameHashMaxSize := nextPowerOf2(serverNames) + if serverNameHashMaxSize > cfg.ServerNameHashMaxSize { + glog.V(3).Infof("adjusting ServerNameHashMaxSize variable from %v to %v", + cfg.ServerNameHashMaxSize, serverNameHashMaxSize) + cfg.ServerNameHashMaxSize = serverNameHashMaxSize + } + + conf := make(map[string]interface{}) + // adjust the size of the backlog + conf["backlogSize"] = sysctlSomaxconn() + conf["upstreams"] = ingressCfg.Upstreams + conf["passthroughUpstreams"] = ingressCfg.PassthroughUpstreams + conf["servers"] = ingressCfg.Servers + conf["tcpUpstreams"] = ingressCfg.TCPUpstreams + conf["udpUpstreams"] = ingressCfg.UDPUpstreams + conf["healthzURL"] = ingressCfg.HealthzURL + conf["defResolver"] = cfg.Resolver + conf["sslDHParam"] = "" + conf["customErrors"] = len(cfg.CustomHTTPErrors) > 0 + conf["cfg"] = ngx_template.StandarizeKeyNames(cfg) + + return n.t.Write(conf, n.testTemplate) +} + +// http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 +// https://play.golang.org/p/TVSyCcdxUh +func nextPowerOf2(v int) int { + v-- + v |= v >> 1 + v |= v >> 2 + v |= v >> 4 + v |= v >> 8 + v |= v >> 16 + v++ + + return v +} diff --git a/controllers/nginx/pkg/cmd/controller/utils.go b/controllers/nginx/pkg/cmd/controller/utils.go new file mode 100644 index 0000000000..5a043abe4d --- /dev/null +++ b/controllers/nginx/pkg/cmd/controller/utils.go @@ -0,0 +1,62 @@ +/* +Copyright 2015 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 main + +import ( + "io/ioutil" + "os" + "os/exec" + + "k8s.io/kubernetes/pkg/util/sysctl" + + "github.com/golang/glog" +) + +// sysctlSomaxconn returns the value of net.core.somaxconn, i.e. +// maximum number of connections that can be queued for acceptance +// http://nginx.org/en/docs/http/ngx_http_core_module.html#listen +func sysctlSomaxconn() int { + maxConns, err := sysctl.New().GetSysctl("net/core/somaxconn") + if err != nil || maxConns < 512 { + glog.V(3).Infof("system net.core.somaxconn=%v (using system default)", maxConns) + return 511 + } + + return maxConns +} + +func diff(b1, b2 []byte) ([]byte, error) { + f1, err := ioutil.TempFile("", "a") + if err != nil { + return nil, err + } + defer f1.Close() + defer os.Remove(f1.Name()) + + f2, err := ioutil.TempFile("", "b") + if err != nil { + return nil, err + } + defer f2.Close() + defer os.Remove(f2.Name()) + + f1.Write(b1) + f2.Write(b2) + + out, _ := exec.Command("diff", "-u", f1.Name(), f2.Name()).CombinedOutput() + return out, nil +} diff --git a/controllers/nginx/pkg/cmd/controller/utils_test.go b/controllers/nginx/pkg/cmd/controller/utils_test.go new file mode 100644 index 0000000000..c506525c27 --- /dev/null +++ b/controllers/nginx/pkg/cmd/controller/utils_test.go @@ -0,0 +1,41 @@ +/* +Copyright 2015 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 main + +import "testing" + +func TestDiff(t *testing.T) { + tests := []struct { + a []byte + b []byte + empty bool + }{ + {[]byte(""), []byte(""), true}, + {[]byte("a"), []byte("a"), true}, + {[]byte("a"), []byte("b"), false}, + } + + for _, test := range tests { + b, err := diff(test.a, test.b) + if err != nil { + t.Fatalf("unexpected error returned: %v", err) + } + if len(b) == 0 && !test.empty { + t.Fatalf("expected empty but returned %s", b) + } + } +} diff --git a/controllers/nginx/nginx/config/config.go b/controllers/nginx/pkg/config/config.go similarity index 74% rename from controllers/nginx/nginx/config/config.go rename to controllers/nginx/pkg/config/config.go index 066440bbd9..3ef7ea7bbe 100644 --- a/controllers/nginx/nginx/config/config.go +++ b/controllers/nginx/pkg/config/config.go @@ -18,7 +18,8 @@ package config import ( "runtime" - "strconv" + + "k8s.io/ingress/core/pkg/ingress/defaults" "github.com/golang/glog" ) @@ -42,7 +43,7 @@ const ( // If UseProxyProtocol is enabled defIPCIDR defines the default the IP/network address of your external load balancer defIPCIDR = "0.0.0.0/0" - gzipTypes = "application/atom+xml application/javascript aplication/x-javascript application/json application/rss+xml application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/svg+xml image/x-icon text/css text/plain text/x-component" + gzipTypes = "application/atom+xml application/javascript application/x-javascript application/json application/rss+xml application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/svg+xml image/x-icon text/css text/plain text/x-component" // http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_buffer_size // Sets the size of the buffer used for sending data. @@ -69,18 +70,17 @@ const ( var ( // SSLDirectory contains the mounted secrets with SSL certificates, keys and - SSLDirectory = "/etc/nginx-ssl" + SSLDirectory = "/etc/ingress-controller/ssl" ) // Configuration represents the content of nginx.conf file type Configuration struct { + defaults.Backend + // http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size // Sets the maximum allowed size of the client request body BodySize string `structs:"body-size,omitempty"` - // HealthzURL defines the URL should be used in probes - HealthzURL string - // EnableDynamicTLSRecords enables dynamic TLS record sizes // https://blog.cloudflare.com/optimizing-tls-over-tcp-to-reduce-latency // By default this is enabled @@ -126,12 +126,6 @@ type Configuration struct { // accessed using HTTPS. HSTSMaxAge string `structs:"hsts-max-age,omitempty"` - // enables which HTTP codes should be passed for processing with the error_page directive - // http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_intercept_errors - // http://nginx.org/en/docs/http/ngx_http_core_module.html#error_page - // By default this is disabled - CustomHTTPErrors []int `structs:"custom-http-errors,-"` - // Time during which a keep-alive client connection will stay open on the server side. // The zero value disables keep-alive client connections // http://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_timeout @@ -146,34 +140,10 @@ type Configuration struct { // http://nginx.org/en/docs/http/ngx_http_map_module.html#map_hash_bucket_size MapHashBucketSize int `structs:"map-hash-bucket-size,omitempty"` - // Defines a timeout for establishing a connection with a proxied server. - // It should be noted that this timeout cannot usually exceed 75 seconds. - // http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_connect_timeout - ProxyConnectTimeout int `structs:"proxy-connect-timeout,omitempty"` - // If UseProxyProtocol is enabled ProxyRealIPCIDR defines the default the IP/network address // of your external load balancer ProxyRealIPCIDR string `structs:"proxy-real-ip-cidr,omitempty"` - // Timeout in seconds for reading a response from the proxied server. The timeout is set only between - // two successive read operations, not for the transmission of the whole response - // http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_read_timeout - ProxyReadTimeout int `structs:"proxy-read-timeout,omitempty"` - - // Timeout in seconds for transmitting a request to the proxied server. The timeout is set only between - // two successive write operations, not for the transmission of the whole request. - // http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_send_timeout - ProxySendTimeout int `structs:"proxy-send-timeout,omitempty"` - - // Sets the size of the buffer used for reading the first part of the response received from the - // proxied server. This part usually contains a small response header. - // http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size) - ProxyBufferSize string `structs:"proxy-buffer-size,omitempty"` - - // Configures name servers used to resolve names of upstream servers into addresses - // http://nginx.org/en/docs/http/ngx_http_core_module.html#resolver - Resolver string `structs:"resolver,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 @@ -185,20 +155,6 @@ type Configuration struct { // http://nginx.org/en/docs/http/ngx_http_core_module.html#server_names_hash_bucket_size ServerNameHashBucketSize int `structs:"server-name-hash-bucket-size,omitempty"` - // SkipAccessLogURLs sets a list of URLs that should not appear in the NGINX access log - // This is useful with urls like `/health` or `health-check` that make "complex" reading the logs - // By default this list is empty - SkipAccessLogURLs []string `structs:"skip-access-log-urls,-"` - - // Enables or disables the redirect (301) to the HTTPS port - SSLRedirect bool `structs:"ssl-redirect,omitempty"` - - // http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_buffer_size - // Sets the size of the buffer used for sending data. - // 4k helps NGINX to improve TLS Time To First Byte (TTTFB) - // https://www.igvita.com/2013/12/16/optimizing-nginx-tls-time-to-first-byte/ - SSLBufferSize string `structs:"ssl-buffer-size,omitempty"` - // Enabled ciphers list to enabled. The ciphers are specified in the format understood by // the OpenSSL library // http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_ciphers @@ -230,17 +186,11 @@ type Configuration struct { // http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_timeout SSLSessionTimeout string `structs:"ssl-session-timeout,omitempty"` - // Number of unsuccessful attempts to communicate with the server that should happen in the - // duration set by the fail_timeout parameter to consider the server unavailable - // http://nginx.org/en/docs/http/ngx_http_upstream_module.html#upstream - // Default: 0, ie use platform liveness probe - UpstreamMaxFails int `structs:"upstream-max-fails,omitempty"` - - // Time during which the specified number of unsuccessful attempts to communicate with - // the server should happen to consider the server unavailable - // http://nginx.org/en/docs/http/ngx_http_upstream_module.html#upstream - // Default: 0, ie use platform liveness probe - UpstreamFailTimeout int `structs:"upstream-fail-timeout,omitempty"` + // http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_buffer_size + // Sets the size of the buffer used for sending data. + // 4k helps NGINX to improve TLS Time To First Byte (TTTFB) + // https://www.igvita.com/2013/12/16/optimizing-nginx-tls-time-to-first-byte/ + SSLBufferSize string `structs:"ssl-buffer-size,omitempty"` // Enables or disables the use of the PROXY protocol to receive client connection // (real IP address) information passed through proxy servers and load balancers @@ -261,13 +211,9 @@ type Configuration struct { // Responses with the “text/html” type are always compressed if UseGzip is enabled GzipTypes string `structs:"gzip-types,omitempty"` - // WhitelistSourceRange allows limiting access to certain client addresses - // http://nginx.org/en/docs/http/ngx_http_access_module.html - WhitelistSourceRange []string `structs:"whitelist-source-range,omitempty"` - // Defines the number of worker processes. By default auto means number of available CPU cores // http://nginx.org/en/docs/ngx_core_module.html#worker_processes - WorkerProcesses string `structs:"worker-processes,omitempty"` + WorkerProcesses int `structs:"worker-processes,omitempty"` } // NewDefault returns the default configuration contained @@ -276,7 +222,7 @@ func NewDefault() Configuration { cfg := Configuration{ BodySize: bodySize, EnableDynamicTLSRecords: true, - EnableSPDY: true, + EnableSPDY: false, ErrorLogLevel: errorLevel, HSTS: true, HSTSIncludeSubdomains: true, @@ -285,14 +231,9 @@ func NewDefault() Configuration { KeepAlive: 75, MaxWorkerConnections: 16384, MapHashBucketSize: 64, - ProxyConnectTimeout: 5, ProxyRealIPCIDR: defIPCIDR, - ProxyReadTimeout: 60, - ProxySendTimeout: 60, - ProxyBufferSize: "4k", ServerNameHashMaxSize: 512, ServerNameHashBucketSize: 64, - SSLRedirect: true, SSLBufferSize: sslBufferSize, SSLCiphers: sslCiphers, SSLProtocols: sslProtocols, @@ -302,12 +243,19 @@ func NewDefault() Configuration { SSLSessionTimeout: sslSessionTimeout, UseProxyProtocol: false, UseGzip: true, - WorkerProcesses: strconv.Itoa(runtime.NumCPU()), + WorkerProcesses: runtime.NumCPU(), VtsStatusZoneSize: "10m", UseHTTP2: true, - CustomHTTPErrors: make([]int, 0), - WhitelistSourceRange: make([]string, 0), - SkipAccessLogURLs: make([]string, 0), + Backend: defaults.Backend{ + ProxyConnectTimeout: 5, + ProxyReadTimeout: 60, + ProxySendTimeout: 60, + ProxyBufferSize: "4k", + SSLRedirect: true, + CustomHTTPErrors: []int{}, + WhitelistSourceRange: []string{}, + SkipAccessLogURLs: []string{}, + }, } if glog.V(5) { diff --git a/controllers/nginx/pkg/template/configmap.go b/controllers/nginx/pkg/template/configmap.go new file mode 100644 index 0000000000..b110b403c2 --- /dev/null +++ b/controllers/nginx/pkg/template/configmap.go @@ -0,0 +1,122 @@ +/* +Copyright 2015 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 template + +import ( + "strconv" + "strings" + + "github.com/golang/glog" + "github.com/imdario/mergo" + + "github.com/fatih/structs" + "github.com/mitchellh/mapstructure" + go_camelcase "github.com/segmentio/go-camelcase" + + "k8s.io/ingress/controllers/nginx/pkg/config" + "k8s.io/ingress/core/pkg/ingress/defaults" + + "k8s.io/kubernetes/pkg/api" +) + +const ( + customHTTPErrors = "custom-http-errors" + skipAccessLogUrls = "skip-access-log-urls" + whitelistSourceRange = "whitelist-source-range" +) + +// StandarizeKeyNames ... +func StandarizeKeyNames(data interface{}) map[string]interface{} { + return fixKeyNames(structs.Map(data)) +} + +// ReadConfig obtains the configuration defined by the user merged with the defaults. +func ReadConfig(conf *api.ConfigMap) config.Configuration { + if len(conf.Data) == 0 { + return config.NewDefault() + } + + var errors []int + var skipUrls []string + var whitelist []string + + if val, ok := conf.Data[customHTTPErrors]; ok { + delete(conf.Data, customHTTPErrors) + for _, i := range strings.Split(val, ",") { + j, err := strconv.Atoi(i) + if err != nil { + glog.Warningf("%v is not a valid http code: %v", i, err) + } else { + errors = append(errors, j) + } + } + } + if val, ok := conf.Data[skipAccessLogUrls]; ok { + delete(conf.Data, skipAccessLogUrls) + skipUrls = strings.Split(val, ",") + } + if val, ok := conf.Data[whitelistSourceRange]; ok { + delete(conf.Data, whitelistSourceRange) + whitelist = append(whitelist, strings.Split(val, ",")...) + } + + to := config.Configuration{} + to.Backend = defaults.Backend{ + CustomHTTPErrors: filterErrors(errors), + SkipAccessLogURLs: skipUrls, + WhitelistSourceRange: whitelist, + } + def := config.NewDefault() + if err := mergo.Merge(&to, def); err != nil { + glog.Warningf("unexpected error merging defaults: %v", err) + } + + metadata := &mapstructure.Metadata{} + decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ + TagName: "structs", + Result: &to, + WeaklyTypedInput: true, + Metadata: metadata, + }) + + err = decoder.Decode(conf.Data) + if err != nil { + glog.Infof("%v", err) + } + return to +} + +func filterErrors(codes []int) []int { + var fa []int + for _, code := range codes { + if code > 299 && code < 600 { + fa = append(fa, code) + } else { + glog.Warningf("error code %v is not valid for custom error pages", code) + } + } + + return fa +} + +func fixKeyNames(data map[string]interface{}) map[string]interface{} { + fixed := make(map[string]interface{}) + for k, v := range data { + fixed[go_camelcase.Camelcase(k)] = v + } + return fixed +} diff --git a/controllers/nginx/pkg/template/configmap_test.go b/controllers/nginx/pkg/template/configmap_test.go new file mode 100644 index 0000000000..e80a299172 --- /dev/null +++ b/controllers/nginx/pkg/template/configmap_test.go @@ -0,0 +1,83 @@ +/* +Copyright 2015 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 template + +import ( + "testing" + + "k8s.io/ingress/controllers/nginx/pkg/config" +) + +func TestStandarizeKeyNames(t *testing.T) { +} + +func TestFilterErrors(t *testing.T) { + e := filterErrors([]int{200, 300, 345, 500, 555, 999}) + if len(e) != 4 { + t.Errorf("expected 4 elements but %v returned", len(e)) + } +} + +func TestFixKeyNames(t *testing.T) { + d := map[string]interface{}{ + "one": "one", + "one-example": "oneExample", + "aMore-complex_example": "aMoreComplexExample", + "a": "a", + } + + fixed := fixKeyNames(d) + for k, v := range fixed { + if k != v { + t.Errorf("expected %v but retuned %v", v, k) + } + } +} + +type testStruct struct { + ProxyReadTimeout int `structs:"proxy-read-timeout,omitempty"` + ProxySendTimeout int `structs:"proxy-send-timeout,omitempty"` + CustomHTTPErrors []int `structs:"custom-http-errors"` + SkipAccessLogURLs []string `structs:"skip-access-log-urls,-"` + NoTag string +} + +var decodedData = &testStruct{ + 1, + 2, + []int{300, 400}, + []string{"/log"}, + "", +} + +func TestMergeConfigMapToStruct(t *testing.T) { + /*conf := &api.ConfigMap{ + Data: map[string]string{ + "custom-http-errors": "300,400", + "proxy-read-timeout": "1", + "proxy-send-timeout": "2", + "skip-access-log-urls": "/log", + }, + }*/ + def := config.NewDefault() + def.CustomHTTPErrors = []int{300, 400} + def.SkipAccessLogURLs = []string{"/log"} + //to := ReadConfig(conf) + //if !reflect.DeepEqual(def, to) { + // t.Errorf("expected %v but retuned %v", def, to) + //} +} diff --git a/controllers/nginx/nginx/template/template.go b/controllers/nginx/pkg/template/template.go similarity index 61% rename from controllers/nginx/nginx/template/template.go rename to controllers/nginx/pkg/template/template.go index a7e7a18a11..fcdef3af1c 100644 --- a/controllers/nginx/nginx/template/template.go +++ b/controllers/nginx/pkg/template/template.go @@ -21,51 +21,28 @@ import ( "encoding/base64" "encoding/json" "fmt" - "regexp" + "os/exec" "strings" text_template "text/template" - "github.com/fatih/structs" "github.com/golang/glog" - "k8s.io/contrib/ingress/controllers/nginx/nginx/config" - "k8s.io/contrib/ingress/controllers/nginx/nginx/ingress" - "k8s.io/kubernetes/pkg/util/sysctl" + "k8s.io/ingress/core/pkg/ingress" + "k8s.io/ingress/core/pkg/watch" ) const ( - slash = "/" -) - -var ( - camelRegexp = regexp.MustCompile("[0-9A-Za-z]+") - - funcMap = text_template.FuncMap{ - "empty": func(input interface{}) bool { - check, ok := input.(string) - if ok { - return len(check) == 0 - } - - return true - }, - "buildLocation": buildLocation, - "buildAuthLocation": buildAuthLocation, - "buildProxyPass": buildProxyPass, - "buildRateLimitZones": buildRateLimitZones, - "buildRateLimit": buildRateLimit, - "contains": strings.Contains, - "hasPrefix": strings.HasPrefix, - "hasSuffix": strings.HasSuffix, - "toUpper": strings.ToUpper, - "toLower": strings.ToLower, - } + slash = "/" + defBufferSize = 65535 ) // Template ... type Template struct { - tmpl *text_template.Template - fw fileWatcher + tmpl *text_template.Template + fw watch.FileWatcher + s int + tmplBuf *bytes.Buffer + outCmdBuf *bytes.Buffer } //NewTemplate returns a new Template instance or an @@ -75,66 +52,32 @@ func NewTemplate(file string, onChange func()) (*Template, error) { if err != nil { return nil, err } - fw, err := newFileWatcher(file, onChange) + fw, err := watch.NewFileWatcher(file, onChange) if err != nil { return nil, err } return &Template{ - tmpl: tmpl, - fw: fw, + tmpl: tmpl, + fw: fw, + s: defBufferSize, + tmplBuf: bytes.NewBuffer(make([]byte, 0, defBufferSize)), + outCmdBuf: bytes.NewBuffer(make([]byte, 0, defBufferSize)), }, nil } // Close removes the file watcher func (t *Template) Close() { - t.fw.close() + t.fw.Close() } // Write populates a buffer using a template with NGINX configuration // and the servers and upstreams created by Ingress rules -func (t *Template) Write( - cfg config.Configuration, - ingressCfg ingress.Configuration, +func (t *Template) Write(conf map[string]interface{}, isValidTemplate func([]byte) error) ([]byte, error) { - var longestName int - var serverNames int - for _, srv := range ingressCfg.Servers { - serverNames += len([]byte(srv.Name)) - if longestName < len(srv.Name) { - longestName = len(srv.Name) - } - } - // NGINX cannot resize the has tables used to store server names. - // For this reason we check if the defined size defined is correct - // for the FQDN defined in the ingress rules adjusting the value - // if is required. - // https://trac.nginx.org/nginx/ticket/352 - // https://trac.nginx.org/nginx/ticket/631 - nameHashBucketSize := nextPowerOf2(longestName) - if nameHashBucketSize > cfg.ServerNameHashBucketSize { - glog.V(3).Infof("adjusting ServerNameHashBucketSize variable from %v to %v", - cfg.ServerNameHashBucketSize, nameHashBucketSize) - cfg.ServerNameHashBucketSize = nameHashBucketSize - } - serverNameHashMaxSize := nextPowerOf2(serverNames) - if serverNameHashMaxSize > cfg.ServerNameHashMaxSize { - glog.V(3).Infof("adjusting ServerNameHashMaxSize variable from %v to %v", - cfg.ServerNameHashMaxSize, serverNameHashMaxSize) - cfg.ServerNameHashMaxSize = serverNameHashMaxSize - } - - conf := make(map[string]interface{}) - conf["backlogSize"] = sysctlSomaxconn() - conf["upstreams"] = ingressCfg.Upstreams - conf["servers"] = ingressCfg.Servers - conf["tcpUpstreams"] = ingressCfg.TCPUpstreams - conf["udpUpstreams"] = ingressCfg.UDPUpstreams - conf["defResolver"] = cfg.Resolver - conf["sslDHParam"] = cfg.SSLDHParam - conf["customErrors"] = len(cfg.CustomHTTPErrors) > 0 - conf["cfg"] = fixKeyNames(structs.Map(cfg)) + defer t.tmplBuf.Reset() + defer t.outCmdBuf.Reset() if glog.V(3) { b, err := json.Marshal(conf) @@ -144,39 +87,65 @@ func (t *Template) Write( glog.Infof("NGINX configuration: %v", string(b)) } - buffer := new(bytes.Buffer) - err := t.tmpl.Execute(buffer, conf) - if err != nil { - glog.V(3).Infof("%v", string(buffer.Bytes())) - return nil, err + err := t.tmpl.Execute(t.tmplBuf, conf) + + if t.s < t.tmplBuf.Cap() { + glog.V(2).Infof("adjusting template buffer size from %v to %v", t.s, t.tmplBuf.Cap()) + t.s = t.tmplBuf.Cap() + t.tmplBuf = bytes.NewBuffer(make([]byte, 0, t.tmplBuf.Cap())) + t.outCmdBuf = bytes.NewBuffer(make([]byte, 0, t.outCmdBuf.Cap())) + } + + // squeezes multiple adjacent empty lines to be single + // spaced this is to avoid the use of regular expressions + cmd := exec.Command("/ingress-controller/clean-nginx-conf.sh") + cmd.Stdin = t.tmplBuf + cmd.Stdout = t.outCmdBuf + if err := cmd.Run(); err != nil { + glog.Warningf("unexpected error cleaning template: %v", err) + return t.tmplBuf.Bytes(), nil } - err = isValidTemplate(buffer.Bytes()) + content := t.outCmdBuf.Bytes() + err = isValidTemplate(content) if err != nil { return nil, err } - return buffer.Bytes(), nil + return content, nil } -func fixKeyNames(data map[string]interface{}) map[string]interface{} { - fixed := make(map[string]interface{}) - for k, v := range data { - fixed[toCamelCase(k)] = v +var ( + funcMap = text_template.FuncMap{ + "empty": func(input interface{}) bool { + check, ok := input.(string) + if ok { + return len(check) == 0 + } + return true + }, + "buildLocation": buildLocation, + "buildAuthLocation": buildAuthLocation, + "buildProxyPass": buildProxyPass, + "buildRateLimitZones": buildRateLimitZones, + "buildRateLimit": buildRateLimit, + "getSSPassthroughUpstream": getSSPassthroughUpstream, + + "contains": strings.Contains, + "hasPrefix": strings.HasPrefix, + "hasSuffix": strings.HasSuffix, + "toUpper": strings.ToUpper, + "toLower": strings.ToLower, } +) - return fixed -} - -func toCamelCase(src string) string { - byteSrc := []byte(src) - chunks := camelRegexp.FindAll(byteSrc, -1) - for idx, val := range chunks { - if idx > 0 { - chunks[idx] = bytes.Title(val) - } +func getSSPassthroughUpstream(input interface{}) string { + s, ok := input.(*ingress.Server) + if !ok { + return "" } - return string(bytes.Join(chunks, nil)) + + return s.Name } // buildLocation produces the location string, if the ingress has redirects @@ -201,7 +170,7 @@ func buildAuthLocation(input interface{}) string { return "" } - if location.ExternalAuthURL.URL == "" { + if location.ExternalAuth.URL == "" { return "" } @@ -329,30 +298,3 @@ func buildRateLimit(input interface{}) []string { return limits } - -// sysctlSomaxconn returns the value of net.core.somaxconn, i.e. -// maximum number of connections that can be queued for acceptance -// http://nginx.org/en/docs/http/ngx_http_core_module.html#listen -func sysctlSomaxconn() int { - maxConns, err := sysctl.New().GetSysctl("net/core/somaxconn") - if err != nil || maxConns < 512 { - glog.Warningf("system net.core.somaxconn=%v. Using NGINX default (511)", maxConns) - return 511 - } - - return maxConns -} - -// http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 -// https://play.golang.org/p/TVSyCcdxUh -func nextPowerOf2(v int) int { - v-- - v |= v >> 1 - v |= v >> 2 - v |= v >> 4 - v |= v >> 8 - v |= v >> 16 - v++ - - return v -} diff --git a/controllers/nginx/nginx/template/template_test.go b/controllers/nginx/pkg/template/template_test.go similarity index 96% rename from controllers/nginx/nginx/template/template_test.go rename to controllers/nginx/pkg/template/template_test.go index 1ca93c025e..00d531c324 100644 --- a/controllers/nginx/nginx/template/template_test.go +++ b/controllers/nginx/pkg/template/template_test.go @@ -20,8 +20,8 @@ import ( "strings" "testing" - "k8s.io/contrib/ingress/controllers/nginx/nginx/ingress" - "k8s.io/contrib/ingress/controllers/nginx/nginx/rewrite" + "k8s.io/ingress/core/pkg/ingress" + "k8s.io/ingress/core/pkg/ingress/annotations/rewrite" ) var ( diff --git a/controllers/nginx/pkg/version/version.go b/controllers/nginx/pkg/version/version.go new file mode 100644 index 0000000000..3c036c0bca --- /dev/null +++ b/controllers/nginx/pkg/version/version.go @@ -0,0 +1,26 @@ +/* +Copyright 2015 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 version + +var ( + // RELEASE returns the release version + RELEASE = "UNKNOWN" + // REPO returns the git repository URL + REPO = "UNKNOWN" + // COMMIT returns the short sha from git + COMMIT = "UNKNOWN" +) diff --git a/controllers/nginx/Dockerfile b/controllers/nginx/rootfs/Dockerfile similarity index 78% rename from controllers/nginx/Dockerfile rename to controllers/nginx/rootfs/Dockerfile index ab4997e927..f5a6abaf75 100644 --- a/controllers/nginx/Dockerfile +++ b/controllers/nginx/rootfs/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM gcr.io/google_containers/nginx-slim:0.9 +FROM gcr.io/google_containers/nginx-slim:0.10 RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y \ diffutils \ @@ -21,13 +21,6 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y \ && rm -rf /var/lib/apt/lists/* \ && make-ssl-cert generate-default-snakeoil --force-overwrite -COPY nginx-ingress-controller / -COPY nginx.tmpl /etc/nginx/template/nginx.tmpl -COPY nginx.tmpl /etc/nginx/nginx.tmpl -COPY default.conf /etc/nginx/nginx.conf - -COPY lua /etc/nginx/lua/ - -WORKDIR / +COPY . / CMD ["/nginx-ingress-controller"] diff --git a/controllers/nginx/lua/error_page.lua b/controllers/nginx/rootfs/etc/nginx/lua/error_page.lua similarity index 100% rename from controllers/nginx/lua/error_page.lua rename to controllers/nginx/rootfs/etc/nginx/lua/error_page.lua diff --git a/controllers/nginx/lua/trie.lua b/controllers/nginx/rootfs/etc/nginx/lua/trie.lua similarity index 100% rename from controllers/nginx/lua/trie.lua rename to controllers/nginx/rootfs/etc/nginx/lua/trie.lua diff --git a/controllers/nginx/lua/vendor/lua-resty-http/.gitignore b/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/.gitignore similarity index 100% rename from controllers/nginx/lua/vendor/lua-resty-http/.gitignore rename to controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/.gitignore diff --git a/controllers/nginx/lua/vendor/lua-resty-http/LICENSE b/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/LICENSE similarity index 100% rename from controllers/nginx/lua/vendor/lua-resty-http/LICENSE rename to controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/LICENSE diff --git a/controllers/nginx/lua/vendor/lua-resty-http/Makefile b/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/Makefile similarity index 100% rename from controllers/nginx/lua/vendor/lua-resty-http/Makefile rename to controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/Makefile diff --git a/controllers/nginx/lua/vendor/lua-resty-http/README.md b/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/README.md similarity index 96% rename from controllers/nginx/lua/vendor/lua-resty-http/README.md rename to controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/README.md index 9ad07f03d4..f0135ffe4c 100644 --- a/controllers/nginx/lua/vendor/lua-resty-http/README.md +++ b/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/README.md @@ -1,21 +1,21 @@ # lua-resty-http -Lua HTTP client cosocket driver for [OpenResty](http://openresty.org/) / [ngx_lua](https://github.com/chaoslawful/lua-nginx-module). +Lua HTTP client cosocket driver for [OpenResty](http://openresty.org/) / [ngx_lua](https://github.com/openresty/lua-nginx-module). # Status -Ready for testing. Probably production ready in most cases, though not yet proven in the wild. Please check the issues list and let me know if you have any problems / questions. +Production ready. # Features * HTTP 1.0 and 1.1 -* Streaming interface to reading bodies using coroutines, for predictable memory usage in Lua land. -* Alternative simple interface for singleshot requests without manual connection step. -* Headers treated case insensitively. -* Chunked transfer encoding. -* Keepalive. -* Pipelining. -* Trailers. +* SSL +* Streaming interface to the response body, for predictable memory usage +* Alternative simple interface for singleshot requests without manual connection step +* Chunked and non-chunked transfer encodings +* Keepalive +* Pipelining +* Trailers # API @@ -222,6 +222,7 @@ The `params` table accepts the following fields: When the request is successful, `res` will contain the following fields: * `status` The status code. +* `reason` The status reason phrase. * `headers` A table of headers. Multiple headers with the same field name will be presented as a table of values. * `has_body` A boolean flag indicating if there is a body to be read. * `body_reader` An iterator function for reading the body in a streaming fashion. @@ -291,7 +292,7 @@ repeat ngx.log(ngx.ERR, err) break end - + if chunk then -- process end @@ -410,7 +411,7 @@ Originally started life based on https://github.com/bakins/lua-resty-http-simple This module is licensed under the 2-clause BSD license. -Copyright (c) 2013, James Hurst +Copyright (c) 2013-2016, James Hurst All rights reserved. diff --git a/controllers/nginx/lua/vendor/lua-resty-http/lib/resty/http.lua b/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/lib/resty/http.lua similarity index 92% rename from controllers/nginx/lua/vendor/lua-resty-http/lib/resty/http.lua rename to controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/lib/resty/http.lua index 3a6a01a0c8..94f9813ef6 100644 --- a/controllers/nginx/lua/vendor/lua-resty-http/lib/resty/http.lua +++ b/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/lib/resty/http.lua @@ -67,7 +67,7 @@ end local _M = { - _VERSION = '0.07', + _VERSION = '0.09', } _M._USER_AGENT = "lua-resty-http/" .. _M._VERSION .. " (Lua) ngx_lua/" .. ngx.config.ngx_lua_version @@ -111,6 +111,8 @@ function _M.ssl_handshake(self, ...) return nil, "not initialized" end + self.ssl = true + return sock:sslhandshake(...) end @@ -122,6 +124,13 @@ function _M.connect(self, ...) end self.host = select(1, ...) + self.port = select(2, ...) + + -- If port is not a number, this is likely a unix domain socket connection. + if type(self.port) ~= "number" then + self.port = nil + end + self.keepalive = true return sock:connect(...) @@ -179,17 +188,19 @@ end function _M.parse_uri(self, uri) - local m, err = ngx_re_match(uri, [[^(http[s]*)://([^:/]+)(?::(\d+))?(.*)]], + local m, err = ngx_re_match(uri, [[^(http[s]?)://([^:/]+)(?::(\d+))?(.*)]], "jo") if not m then if err then - return nil, "failed to match the uri: " .. err + return nil, "failed to match the uri: " .. uri .. ", " .. err end - return nil, "bad uri" + return nil, "bad uri: " .. uri else - if not m[3] then + if m[3] then + m[3] = tonumber(m[3]) + else if m[1] == "https" then m[3] = 443 else @@ -250,10 +261,10 @@ end local function _receive_status(sock) local line, err = sock:receive("*l") if not line then - return nil, nil, err + return nil, nil, nil, err end - return tonumber(str_sub(line, 10, 12)), tonumber(str_sub(line, 6, 8)) + return tonumber(str_sub(line, 10, 12)), tonumber(str_sub(line, 6, 8)), str_sub(line, 14) end @@ -487,16 +498,16 @@ end local function _handle_continue(sock, body) - local status, version, err = _receive_status(sock) + local status, version, reason, err = _receive_status(sock) if not status then - return nil, err + return nil, nil, err end -- Only send body if we receive a 100 Continue if status == 100 then local ok, err = sock:receive("*l") -- Read carriage return if not ok then - return nil, err + return nil, nil, err end _send_body(sock, body) end @@ -526,7 +537,22 @@ function _M.send_request(self, params) headers["Content-Length"] = #body end if not headers["Host"] then - headers["Host"] = self.host + if (str_sub(self.host, 1, 5) == "unix:") then + return nil, "Unable to generate a useful Host header for a unix domain socket. Please provide one." + end + -- If we have a port (i.e. not connected to a unix domain socket), and this + -- port is non-standard, append it to the Host heaer. + if self.port then + if self.ssl and self.port ~= 443 then + headers["Host"] = self.host .. ":" .. self.port + elseif not self.ssl and self.port ~= 80 then + headers["Host"] = self.host .. ":" .. self.port + else + headers["Host"] = self.host + end + else + headers["Host"] = self.host + end end if not headers["User-Agent"] then headers["User-Agent"] = _M._USER_AGENT @@ -562,7 +588,7 @@ end function _M.read_response(self, params) local sock = self.sock - local status, version, err + local status, version, reason, err -- If we expect: continue, we need to handle this, sending the body if allowed. -- If we don't get 100 back, then status is the actual status. @@ -577,7 +603,7 @@ function _M.read_response(self, params) -- Just read the status as normal. if not status then - status, version, err = _receive_status(sock) + status, version, reason, err = _receive_status(sock) if not status then return nil, err end @@ -589,13 +615,18 @@ function _M.read_response(self, params) return nil, err end - -- Determine if we should keepalive or not. + -- keepalive is true by default. Determine if this is correct or not. local ok, connection = pcall(str_lower, res_headers["Connection"]) if ok then if (version == 1.1 and connection == "close") or (version == 1.0 and connection ~= "keep-alive") then self.keepalive = false end + else + -- no connection header + if version == 1.0 then + self.keepalive = false + end end local body_reader = _no_body_reader @@ -627,6 +658,7 @@ function _M.read_response(self, params) else return { status = status, + reason = reason, headers = res_headers, has_body = has_body, body_reader = body_reader, diff --git a/controllers/nginx/lua/vendor/lua-resty-http/lib/resty/http_headers.lua b/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/lib/resty/http_headers.lua similarity index 100% rename from controllers/nginx/lua/vendor/lua-resty-http/lib/resty/http_headers.lua rename to controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/lib/resty/http_headers.lua diff --git a/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/lua-resty-http-0.09-0.rockspec b/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/lua-resty-http-0.09-0.rockspec new file mode 100644 index 0000000000..589c0ca29d --- /dev/null +++ b/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/lua-resty-http-0.09-0.rockspec @@ -0,0 +1,22 @@ +package = "lua-resty-http" +version = "0.09-0" +source = { + url = "git://github.com/pintsized/lua-resty-http", + tag = "v0.09" +} +description = { + summary = "Lua HTTP client cosocket driver for OpenResty / ngx_lua.", + homepage = "https://github.com/pintsized/lua-resty-http", + license = "2-clause BSD", + maintainer = "James Hurst " +} +dependencies = { + "lua >= 5.1" +} +build = { + type = "builtin", + modules = { + ["resty.http"] = "lib/resty/http.lua", + ["resty.http_headers"] = "lib/resty/http_headers.lua" + } +} diff --git a/controllers/nginx/lua/vendor/lua-resty-http/t/01-basic.t b/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/01-basic.t similarity index 98% rename from controllers/nginx/lua/vendor/lua-resty-http/t/01-basic.t rename to controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/01-basic.t index 03c33c57a8..79d4ee7e05 100644 --- a/controllers/nginx/lua/vendor/lua-resty-http/t/01-basic.t +++ b/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/01-basic.t @@ -83,7 +83,7 @@ OK [warn] -=== TEST 3: Status code +=== TEST 3: Status code and reason phrase --- http_config eval: $::HttpConfig --- config location = /a { @@ -97,6 +97,7 @@ OK } ngx.status = res.status + ngx.say(res.reason) ngx.print(res:read_body()) httpc:close() @@ -111,6 +112,7 @@ OK --- request GET /a --- response_body +Not Found OK --- error_code: 404 --- no_error_log diff --git a/controllers/nginx/lua/vendor/lua-resty-http/t/02-chunked.t b/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/02-chunked.t similarity index 100% rename from controllers/nginx/lua/vendor/lua-resty-http/t/02-chunked.t rename to controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/02-chunked.t diff --git a/controllers/nginx/lua/vendor/lua-resty-http/t/03-requestbody.t b/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/03-requestbody.t similarity index 100% rename from controllers/nginx/lua/vendor/lua-resty-http/t/03-requestbody.t rename to controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/03-requestbody.t diff --git a/controllers/nginx/lua/vendor/lua-resty-http/t/04-trailers.t b/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/04-trailers.t similarity index 100% rename from controllers/nginx/lua/vendor/lua-resty-http/t/04-trailers.t rename to controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/04-trailers.t diff --git a/controllers/nginx/lua/vendor/lua-resty-http/t/05-stream.t b/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/05-stream.t similarity index 100% rename from controllers/nginx/lua/vendor/lua-resty-http/t/05-stream.t rename to controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/05-stream.t diff --git a/controllers/nginx/lua/vendor/lua-resty-http/t/06-simpleinterface.t b/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/06-simpleinterface.t similarity index 100% rename from controllers/nginx/lua/vendor/lua-resty-http/t/06-simpleinterface.t rename to controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/06-simpleinterface.t diff --git a/controllers/nginx/lua/vendor/lua-resty-http/t/07-keepalive.t b/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/07-keepalive.t similarity index 76% rename from controllers/nginx/lua/vendor/lua-resty-http/t/07-keepalive.t rename to controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/07-keepalive.t index cb9bc3aa57..c8bda14079 100644 --- a/controllers/nginx/lua/vendor/lua-resty-http/t/07-keepalive.t +++ b/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/07-keepalive.t @@ -180,3 +180,61 @@ connection must be closed --- no_error_log [error] [warn] + + +=== TEST 5: Generic interface, HTTP 1.0, no connection header. Test we don't try to keepalive, but also that subsequent connections can keepalive. +--- http_config eval: $::HttpConfig +--- config + location = /a { + content_by_lua ' + local http = require "resty.http" + local httpc = http.new() + httpc:connect("127.0.0.1", 12345) + + local res, err = httpc:request{ + version = 1.0, + path = "/b" + } + + local body = res:read_body() + ngx.print(body) + + ngx.say(res.headers["Connection"]) + + local r, e = httpc:set_keepalive() + ngx.say(r) + ngx.say(e) + + httpc:connect("127.0.0.1", ngx.var.server_port) + ngx.say(httpc:get_reused_times()) + + httpc:set_keepalive() + + httpc:connect("127.0.0.1", ngx.var.server_port) + ngx.say(httpc:get_reused_times()) + '; + } + location = /b { + content_by_lua ' + ngx.say("OK") + '; + } +--- request +GET /a +--- tcp_listen: 12345 +--- tcp_reply +HTTP/1.0 200 OK +Date: Fri, 08 Aug 2016 08:12:31 GMT +Server: OpenResty + +OK +--- response_body +OK +nil +2 +connection must be closed +0 +1 +--- no_error_log +[error] +[warn] diff --git a/controllers/nginx/lua/vendor/lua-resty-http/t/08-pipeline.t b/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/08-pipeline.t similarity index 100% rename from controllers/nginx/lua/vendor/lua-resty-http/t/08-pipeline.t rename to controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/08-pipeline.t diff --git a/controllers/nginx/lua/vendor/lua-resty-http/t/09-ssl.t b/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/09-ssl.t similarity index 100% rename from controllers/nginx/lua/vendor/lua-resty-http/t/09-ssl.t rename to controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/09-ssl.t diff --git a/controllers/nginx/lua/vendor/lua-resty-http/t/10-clientbodyreader.t b/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/10-clientbodyreader.t similarity index 100% rename from controllers/nginx/lua/vendor/lua-resty-http/t/10-clientbodyreader.t rename to controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/10-clientbodyreader.t diff --git a/controllers/nginx/lua/vendor/lua-resty-http/t/11-proxy.t b/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/11-proxy.t similarity index 100% rename from controllers/nginx/lua/vendor/lua-resty-http/t/11-proxy.t rename to controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/11-proxy.t diff --git a/controllers/nginx/lua/vendor/lua-resty-http/t/12-case_insensitive_headers.t b/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/12-case_insensitive_headers.t similarity index 100% rename from controllers/nginx/lua/vendor/lua-resty-http/t/12-case_insensitive_headers.t rename to controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/12-case_insensitive_headers.t diff --git a/controllers/nginx/lua/vendor/lua-resty-http/t/13-default-path.t b/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/13-default-path.t similarity index 100% rename from controllers/nginx/lua/vendor/lua-resty-http/t/13-default-path.t rename to controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/13-default-path.t diff --git a/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/14-host-header.t b/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/14-host-header.t new file mode 100644 index 0000000000..e3411ffe46 --- /dev/null +++ b/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/14-host-header.t @@ -0,0 +1,161 @@ +# vim:set ft= ts=4 sw=4 et: + +use Test::Nginx::Socket; +use Cwd qw(cwd); + +plan tests => repeat_each() * (blocks() * 3); + +my $pwd = cwd(); + +our $HttpConfig = qq{ + lua_package_path "$pwd/lib/?.lua;;"; + error_log logs/error.log debug; + resolver 8.8.8.8; +}; + +$ENV{TEST_NGINX_RESOLVER} = '8.8.8.8'; +$ENV{TEST_NGINX_PWD} ||= $pwd; + +sub read_file { + my $infile = shift; + open my $in, $infile + or die "cannot open $infile for reading: $!"; + my $cert = do { local $/; <$in> }; + close $in; + $cert; +} + +our $TestCertificate = read_file("t/cert/test.crt"); +our $TestCertificateKey = read_file("t/cert/test.key"); + +no_long_string(); +#no_diff(); + +run_tests(); + +__DATA__ +=== TEST 1: Default HTTP port is not added to Host header +--- http_config eval: $::HttpConfig +--- config + location /lua { + content_by_lua ' + local http = require "resty.http" + local httpc = http.new() + + local res, err = httpc:request_uri("http://www.google.com") + '; + } +--- request +GET /lua +--- no_error_log +[error] +--- error_log +Host: www.google.com + + +=== TEST 2: Default HTTPS port is not added to Host header +--- http_config eval: $::HttpConfig +--- config + location /lua { + content_by_lua ' + local http = require "resty.http" + local httpc = http.new() + + local res, err = httpc:request_uri("https://www.google.com:443", { ssl_verify = false }) + '; + } +--- request +GET /lua +--- no_error_log +[error] +--- error_log +Host: www.google.com + + +=== TEST 3: Non-default HTTP port is added to Host header +--- http_config + lua_package_path "$TEST_NGINX_PWD/lib/?.lua;;"; + error_log logs/error.log debug; + resolver 8.8.8.8; + server { + listen *:8080; + } +--- config + location /lua { + content_by_lua ' + local http = require "resty.http" + local httpc = http.new() + + local res, err = httpc:request_uri("http://127.0.0.1:8080") + '; + } +--- request +GET /lua +--- no_error_log +[error] +--- error_log +Host: 127.0.0.1:8080 + + +=== TEST 4: Non-default HTTPS port is added to Host header +--- http_config + lua_package_path "$TEST_NGINX_PWD/lib/?.lua;;"; + error_log logs/error.log debug; + resolver 8.8.8.8; + server { + listen *:8080; + listen *:8081 ssl; + ssl_certificate ../html/test.crt; + ssl_certificate_key ../html/test.key; + } +--- config + location /lua { + content_by_lua ' + local http = require "resty.http" + local httpc = http.new() + + local res, err = httpc:request_uri("https://127.0.0.1:8081", { ssl_verify = false }) + '; + } +--- user_files eval +">>> test.key +$::TestCertificateKey +>>> test.crt +$::TestCertificate" +--- request +GET /lua +--- no_error_log +[error] +--- error_log +Host: 127.0.0.1:8081 + + +=== TEST 5: No host header on a unix domain socket returns a useful error. +--- http_config eval: $::HttpConfig +--- config + location /a { + content_by_lua_block { + local http = require "resty.http" + local httpc = http.new() + + local res, err = httpc:connect("unix:test.sock") + if not res then + ngx.log(ngx.ERR, err) + end + + local res, err = httpc:request({ path = "/" }) + if not res then + ngx.say(err) + else + ngx.say(res:read_body()) + end + } + } +--- tcp_listen: test.sock +--- tcp_reply: OK +--- request +GET /a +--- no_error_log +[error] +--- response_body +Unable to generate a useful Host header for a unix domain socket. Please provide one. diff --git a/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/cert/test.crt b/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/cert/test.crt new file mode 100644 index 0000000000..ae1134461d --- /dev/null +++ b/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/cert/test.crt @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIID8DCCAtigAwIBAgIJALL9eJPZ6neGMA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNV +BAYTAkdCMQ0wCwYDVQQIEwRUZXN0MQ0wCwYDVQQHEwRUZXN0MQ0wCwYDVQQKEwRU +ZXN0MQ0wCwYDVQQLEwRUZXN0MQ0wCwYDVQQDEwR0ZXN0MB4XDTE1MTAyMTE2MjQ1 +NloXDTE1MTEyMDE2MjQ1NlowWDELMAkGA1UEBhMCR0IxDTALBgNVBAgTBFRlc3Qx +DTALBgNVBAcTBFRlc3QxDTALBgNVBAoTBFRlc3QxDTALBgNVBAsTBFRlc3QxDTAL +BgNVBAMTBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDz/AoE +c+TPdm+Aqcchq8fLNWksFQZqbsCBGnq8rUG1b6MsVlAOkDUQGRlNPs9v0/+pzgX7 +IYXPCFcV7YONNsTUfvBYTq43mfOycmAdb3SX6kBygxdhYsDRZR+vCAIkjoRmRB20 +meh1motqM58spq3IcT8VADTRJl1OI48VTnxmXdCtmkOymU948DcauMoxm03eL/hU +6eniNEujbnbB305noNG0W5c3h6iz9CvqUAD1kwyjick+f1atB2YYn1bymA+db6YN +3iTo0v2raWmIc7D+qqpkNaCRxgMb2HN6X3/SfkijtNJidjqHMbs2ftlKJ5/lODPZ +rCPQOcYK6TT8MIZ1AgMBAAGjgbwwgbkwHQYDVR0OBBYEFFUC1GrAhUp7IvJH5iyf ++fJQliEIMIGJBgNVHSMEgYEwf4AUVQLUasCFSnsi8kfmLJ/58lCWIQihXKRaMFgx +CzAJBgNVBAYTAkdCMQ0wCwYDVQQIEwRUZXN0MQ0wCwYDVQQHEwRUZXN0MQ0wCwYD +VQQKEwRUZXN0MQ0wCwYDVQQLEwRUZXN0MQ0wCwYDVQQDEwR0ZXN0ggkAsv14k9nq +d4YwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAtaUQOr3Qn87KXmmP +GbSvCLSl+bScE09VYZsYaB6iq0pGN9y+Vh4/HjBUUsFexopw1dY25MEEJXEVi1xV +2krLYAsfKCM6c1QBVmdqfVuxUvxpXwr+CNRNAlzz6PhjkeY/Ds/j4sg7EqN8hMmT +gu8GuogX7+ZCgrzRSMMclWej+W8D1xSIuCC+rqv4w9SZdtVb3XGpCyizpTNsQAuV +ACXvq9KXkEEj+XNvKrNdWd4zG715RdMnVm+WM53d9PLp63P+4/kwhwHULYhXygQ3 +DzzVPaojBBdw3VaHbbPHnv73FtAzOb7ky6zJ01DlmEPxEahCFpklMkY9T2uCdpj9 +oOzaNA== +-----END CERTIFICATE----- diff --git a/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/cert/test.key b/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/cert/test.key new file mode 100644 index 0000000000..4fcd0dae85 --- /dev/null +++ b/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/t/cert/test.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA8/wKBHPkz3ZvgKnHIavHyzVpLBUGam7AgRp6vK1BtW+jLFZQ +DpA1EBkZTT7Pb9P/qc4F+yGFzwhXFe2DjTbE1H7wWE6uN5nzsnJgHW90l+pAcoMX +YWLA0WUfrwgCJI6EZkQdtJnodZqLajOfLKatyHE/FQA00SZdTiOPFU58Zl3QrZpD +splPePA3GrjKMZtN3i/4VOnp4jRLo252wd9OZ6DRtFuXN4eos/Qr6lAA9ZMMo4nJ +Pn9WrQdmGJ9W8pgPnW+mDd4k6NL9q2lpiHOw/qqqZDWgkcYDG9hzel9/0n5Io7TS +YnY6hzG7Nn7ZSief5Tgz2awj0DnGCuk0/DCGdQIDAQABAoIBAGjKc7L94+SHRdTJ +FtILacCJrCZW0W6dKulIajbnYzV+QWMlnzTiEyha31ciBw5My54u8rqt5z7Ioj60 +yK+6OkfaTXhgMsuGv/iAz29VE4q7/fow+7XEKHTHLhiLJAB3hb42u1t6TzFTs1Vl +3pPa8wEIQsPOVuENzT1mYGoST7PW+LBIMr9ScMnRHfC0MNdV/ntQiXideOAd5PkA +4O7fNgYZ8CTAZ8rOLYTMFF76/c/jLiqfeghqbIhqMykk36kd7Lud//FRykVsn1aJ +REUva/SjVEth5kITot1hpMC4SIElWpha2YxiiZFoSXSaUbtHpymiUGV01cYtMWk0 +MZ5HN3ECgYEA/74U8DpwPxd4up9syKyNqOqrCrYnhEEC/tdU/W5wECi4y5kppjdd +88lZzICVPzk2fezYXlCO9HiSHU1UfcEsY3u16qNCvylK7Qz1OqXV/Ncj59891Q5Z +K0UBcbnrv+YD6muZuhlHEbyDPqYO091G9Gf/BbL5JIBDzg1qFO9Dh9cCgYEA9Drt +O9PJ5Sjz3mXQVtVHpwyhOVnd7CUv8a1zkUQCK5uQeaiF5kal1FIo7pLOr3KAvG0C +pXbm/TobwlfAfcERQN88aPN8Z/l1CB0oKV6ipBMD2/XLzDRtx8lpTeh/BB8jIhrz ++FDJY54HCzLfW0P5kT+Cyw51ofjziPnFdO/Z6pMCgYEAon17gEchGnUnWCwDSl2Y +hELV+jBSW02TQag/b+bDfQDiqTnfpKR5JXRBghYQveL0JH5f200EB4C0FboUfPJH +6c2ogDTLK/poiMU66tCDbeqj/adx+fTr4votOL0QdRUIV+GWAxAcf8BvA1cvBJ4L +fy60ckKM2gxFCJ6tUC/VkHECgYBoMDNAUItSnXPbrmeAg5/7naGxy6qmsP6RBUPF +9tNOMyEhJUlqAT2BJEOd8zcFFb3hpEd6uwyzfnSVJcZSX2iy2gj1ZNnvqTXJ7lZR +v7N2dz4wOd1lEgC7OCsaN1LoOThNtl3Z0uz2+FVc66jpUEhJNGThpxt7q66JArS/ +vAqkzQKBgFkzqA6QpnH5KhOCoZcuLQ4MtvnNHOx1xSm2B0gKDVJzGkHexTmOJvwM +ZhHXRl9txS4icejS+AGUXNBzCWEusfhDaZpZqS6zt6UxEjMsLj/Te7z++2KQn4t/ +aI77jClydW1pJvICtqm5v+sukVZvQTTJza9ujta6fj7u2s671np9 +-----END RSA PRIVATE KEY----- diff --git a/controllers/nginx/lua/vendor/lua-resty-http/util/lua-releng b/controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/util/lua-releng similarity index 100% rename from controllers/nginx/lua/vendor/lua-resty-http/util/lua-releng rename to controllers/nginx/rootfs/etc/nginx/lua/vendor/lua-resty-http/util/lua-releng diff --git a/controllers/nginx/default.conf b/controllers/nginx/rootfs/etc/nginx/nginx.conf similarity index 100% rename from controllers/nginx/default.conf rename to controllers/nginx/rootfs/etc/nginx/nginx.conf diff --git a/controllers/nginx/nginx.tmpl b/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl similarity index 72% rename from controllers/nginx/nginx.tmpl rename to controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl index 065560136d..18afc359d3 100644 --- a/controllers/nginx/nginx.tmpl +++ b/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl @@ -1,14 +1,10 @@ -{{ $cfg := .cfg }} +{{ $cfg := .cfg }}{{ $healthzURL := .healthzURL }} daemon off; worker_processes {{ $cfg.workerProcesses }}; - pid /run/nginx.pid; - worker_rlimit_nofile 131072; -pcre_jit on; - events { multi_accept on; worker_connections {{ $cfg.maxWorkerConnections }}; @@ -17,13 +13,13 @@ events { http { {{/* we use the value of the header X-Forwarded-For to be able to use the geo_ip module */}} - {{ if $cfg.useProxyProtocol -}} + {{ if $cfg.useProxyProtocol }} set_real_ip_from {{ $cfg.proxyRealIpCidr }}; real_ip_header proxy_protocol; {{ else }} real_ip_header X-Forwarded-For; set_real_ip_from 0.0.0.0/0; - {{ end -}} + {{ end }} real_ip_recursive on; @@ -34,10 +30,10 @@ http { geoip_city /etc/nginx/GeoLiteCity.dat; geoip_proxy_recursive on; - {{- if $cfg.enableVtsStatus }} + {{ if $cfg.enableVtsStatus }} vhost_traffic_status_zone shared:vhost_traffic_status:{{ $cfg.vtsStatusZoneSize }}; vhost_traffic_status_filter_by_set_key $geoip_country_code country::*; - {{ end -}} + {{ end }} # lua section to return proper error codes when custom pages are used lua_package_path '.?.lua;./etc/nginx/lua/?.lua;/etc/nginx/lua/vendor/lua-resty-http/lib/?.lua;'; @@ -56,32 +52,32 @@ http { keepalive_timeout {{ $cfg.keepAlive }}s; - types_hash_max_size 2048; - server_names_hash_max_size {{ $cfg.serverNameHashMaxSize }}; - server_names_hash_bucket_size {{ $cfg.serverNameHashBucketSize }}; - map_hash_bucket_size {{ $cfg.mapHashBucketSize }}; + types_hash_max_size 2048; + server_names_hash_max_size {{ $cfg.serverNameHashMaxSize }}; + server_names_hash_bucket_size {{ $cfg.serverNameHashBucketSize }}; + map_hash_bucket_size {{ $cfg.mapHashBucketSize }}; include /etc/nginx/mime.types; default_type text/html; - {{ if $cfg.useGzip -}} + {{ if $cfg.useGzip }} gzip on; gzip_comp_level 5; gzip_http_version 1.1; gzip_min_length 256; gzip_types {{ $cfg.gzipTypes }}; gzip_proxied any; - {{- end }} + {{ end }} client_max_body_size "{{ $cfg.bodySize }}"; - log_format upstreaminfo '{{ if $cfg.useProxyProtocol }}$proxy_protocol_addr{{ else }}$remote_addr{{ end }} $host ' - '[$proxy_add_x_forwarded_for] $server_port $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" ' + log_format upstreaminfo '{{ if $cfg.useProxyProtocol }}$proxy_protocol_addr{{ else }}$remote_addr{{ end }} - ' + '[$proxy_add_x_forwarded_for] - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" ' '$request_length $request_time [$proxy_upstream_name] $upstream_addr $upstream_response_length $upstream_response_time $upstream_status'; {{/* map urls that should not appear in access.log */}} {{/* http://nginx.org/en/docs/http/ngx_http_log_module.html#access_log */}} map $request $loggable { - {{- range $reqUri := $cfg.skipAccessLogUrls }} + {{ range $reqUri := $cfg.skipAccessLogUrls }} {{ $reqUri }} 0;{{ end }} default 1; } @@ -155,16 +151,16 @@ http { ssl_dhparam {{ .sslDHParam }}; {{ end }} - {{- if not $cfg.enableDynamicTlsRecords }} + {{ if not $cfg.enableDynamicTlsRecords }} ssl_dyn_rec_size_lo 0; {{ end }} - {{- if .customErrors }} + {{ if .customErrors }} # Custom error pages proxy_intercept_errors on; {{ end }} - {{- range $errCode := $cfg.customHttpErrors }} + {{ range $errCode := $cfg.customHttpErrors }} error_page {{ $errCode }} = @custom_{{ $errCode }};{{ end }} # In case of errors try the next upstream server before returning an error @@ -172,11 +168,11 @@ http { {{range $name, $upstream := .upstreams}} upstream {{$upstream.Name}} { - {{ if $cfg.enableStickySessions -}} + {{ if $cfg.enableStickySessions }} sticky hash=sha1 httponly; - {{ else -}} + {{ else }} least_conn; - {{- end }} + {{ end }} {{ range $server := $upstream.Backends }}server {{ $server.Address }}:{{ $server.Port }} max_fails={{ $server.MaxFails }} fail_timeout={{ $server.FailTimeout }}; {{ end }} } @@ -184,7 +180,7 @@ http { {{/* build all the required rate limit zones. Each annotation requires a dedicated zone */}} {{/* 1MB -> 16 thousand 64-byte states or about 8 thousand 128-byte states */}} - {{- range $zone := (buildRateLimitZones .servers) }} + {{ range $zone := (buildRateLimitZones .servers) }} {{ $zone }} {{ end }} @@ -192,75 +188,85 @@ http { server { server_name {{ $server.Name }}; listen 80{{ if $cfg.useProxyProtocol }} proxy_protocol{{ end }}; - {{ if $server.SSL }}listen 443 {{ if $cfg.useProxyProtocol }}proxy_protocol{{ end }} ssl {{ if $cfg.enableSpdy }}spdy{{ end }} {{ if $cfg.useHttp2 }}http2{{ end }}; + {{ if $server.SSL }}listen 442 {{ if $cfg.useProxyProtocol }}proxy_protocol{{ end }} ssl {{ if $cfg.useHttp2 }}http2{{ end }}; {{/* comment PEM sha is required to detect changes in the generated configuration and force a reload */}} # PEM sha: {{ $server.SSLPemChecksum }} - ssl_certificate {{ $server.SSLCertificate }}; - ssl_certificate_key {{ $server.SSLCertificateKey }}; - {{- end }} - - {{- if (and $server.SSL $cfg.hsts) }} - more_set_headers "Strict-Transport-Security: max-age={{ $cfg.hstsMaxAge }}{{ if $cfg.hstsIncludeSubdomains }}; includeSubDomains{{ end }}; preload"; - {{- end }} + ssl_certificate {{ $server.SSLCertificate }}; + ssl_certificate_key {{ $server.SSLCertificate }}; + {{ end }} + + {{ if (and $server.SSL $cfg.hsts) }} + more_set_headers "Strict-Transport-Security: max-age={{ $cfg.hstsMaxAge }}{{ if $cfg.hstsIncludeSubdomains }}; includeSubDomains{{ end }}; preload"; + {{ end }} - {{ if $cfg.enableVtsStatus }}vhost_traffic_status_filter_by_set_key $geoip_country_code country::$server_name;{{ end -}} + {{ if $cfg.enableVtsStatus }}vhost_traffic_status_filter_by_set_key $geoip_country_code country::$server_name;{{ end }} - {{- range $location := $server.Locations }} + {{ range $location := $server.Locations }} {{ $path := buildLocation $location }} {{ $authPath := buildAuthLocation $location }} - {{- if not (empty $authPath) }} + + {{ if not (empty $location.CertificateAuth.CertFileName) }} + # PEM sha: {{ $location.CertificateAuth.PemSHA }} + ssl_client_certificate {{ $location.CertificateAuth.CAFileName }}; + ssl_verify_client on; + {{ end }} + + {{ if not (empty $authPath) }} location = {{ $authPath }} { internal; - {{ if not $location.ExternalAuthURL.SendBody }} + {{ if not $location.ExternalAuth.SendBody }} proxy_pass_request_body off; proxy_set_header Content-Length ""; - {{ end -}} - {{ if not (empty $location.ExternalAuthURL.Method) }} - proxy_method {{ $location.ExternalAuthURL.Method }}; - {{ end -}} + {{ end }} + {{ if not (empty $location.ExternalAuth.Method) }} + proxy_method {{ $location.ExternalAuth.Method }}; + {{ end }} proxy_set_header Host $host; proxy_pass_request_headers on; - proxy_pass {{ $location.ExternalAuthURL.URL }}; + set $target {{ $location.ExternalAuth.URL }}; + proxy_pass $target; } {{ end }} + location {{ $path }} { - {{- if gt (len $location.Whitelist.CIDR) 0 }} - {{- range $ip := $location.Whitelist.CIDR }} + {{ if gt (len $location.Whitelist.CIDR) 0 }} + {{ range $ip := $location.Whitelist.CIDR }} allow {{ $ip }};{{ end }} deny all; - {{ end -}} - {{- if not (empty $authPath) }} + {{ end }} + + {{ if not (empty $authPath) }} # this location requires authentication auth_request {{ $authPath }}; - {{ end -}} - - {{- if (and $server.SSL $location.Redirect.SSLRedirect) }} + {{ end }} + + {{ if (and $server.SSL $location.Redirect.SSLRedirect) }} # enforce ssl on server side if ($scheme = http) { return 301 https://$host$request_uri; } - {{ end -}} + {{ end }} {{/* if the location contains a rate limit annotation, create one */}} {{ $limits := buildRateLimit $location }} - {{- range $limit := $limits }} + {{ range $limit := $limits }} {{ $limit }}{{ end }} - - {{- if $location.Auth.Secured }} - {{- if eq $location.Auth.Type "basic" }} - auth_basic "{{ $location.Auth.Realm }}"; - auth_basic_user_file {{ $location.Auth.File }}; + + {{ if $location.BasicDigestAuth.Secured }} + {{ if eq $location.BasicDigestAuth.Type "basic" }} + auth_basic "{{ $location.BasicDigestAuth.Realm }}"; + auth_basic_user_file {{ $location.BasicDigestAuth.File }}; {{ else }} #TODO: add nginx-http-auth-digest module - auth_digest "{{ $location.Auth.Realm }}"; - auth_digest_user_file {{ $location.Auth.File }}; - {{ end -}} + auth_digest "{{ $location.BasicDigestAuth.Realm }}"; + auth_digest_user_file {{ $location.BasicDigestAuth.File }}; + {{ end }} proxy_set_header Authorization ""; - {{ end -}} - - {{- if $location.EnableCORS }} + {{ end }} + + {{ if $location.EnableCORS }} {{ template "CORS" }} - {{ end -}} - + {{ end }} + proxy_set_header Host $host; # Pass Real IP @@ -279,29 +285,29 @@ http { # https://www.nginx.com/blog/mitigating-the-httpoxy-vulnerability-with-nginx/ proxy_set_header Proxy ""; - proxy_connect_timeout {{ $cfg.proxyConnectTimeout }}s; - proxy_send_timeout {{ $cfg.proxySendTimeout }}s; - proxy_read_timeout {{ $cfg.proxyReadTimeout }}s; + proxy_connect_timeout {{ $location.Proxy.ConnectTimeout }}s; + proxy_send_timeout {{ $location.Proxy.SendTimeout }}s; + proxy_read_timeout {{ $location.Proxy.ReadTimeout }}s; proxy_redirect off; proxy_buffering off; - proxy_buffer_size {{ $cfg.proxyBufferSize }}; + proxy_buffer_size "{{ $location.Proxy.BufferSize }}"; proxy_http_version 1.1; {{/* rewrite only works if the content is not compressed */}} - {{- if $location.Redirect.AddBaseURL }} + {{ if $location.Redirect.AddBaseURL }} proxy_set_header Accept-Encoding ""; - {{ end -}} + {{ end }} set $proxy_upstream_name "{{ $location.Upstream.Name }}"; {{ buildProxyPass $location }} } {{ end }} - - {{- if eq $server.Name "_" }} + + {{ if eq $server.Name "_" }} # health checks in cloud providers require the use of port 80 - location {{ $cfg.HealthzURL }} { + location {{ $healthzURL }} { access_log off; return 200; } @@ -315,11 +321,12 @@ http { access_log off; stub_status on; } - {{ end -}} + {{ end }} {{ template "CUSTOM_ERRORS" $cfg }} } + {{ end }} - + # default server, used for NGINX healthcheck and access to nginx stats server { # Use the port 18080 (random value just to avoid known ports) as default port for nginx. @@ -327,26 +334,26 @@ http { # https://github.com/kubernetes/contrib/blob/master/ingress/controllers/nginx/nginx/command.go#L104 listen 18080 default_server reuseport backlog={{ .backlogSize }}; - location /healthz { + location {{ $healthzURL }} { access_log off; return 200; } location /nginx_status { - {{ if $cfg.enableVtsStatus -}} + {{ if $cfg.enableVtsStatus }} vhost_traffic_status_display; vhost_traffic_status_display_format html; {{ else }} access_log off; stub_status on; - {{- end }} + {{ end }} } location / { set $proxy_upstream_name "upstream-default-backend"; proxy_pass http://upstream-default-backend; } - {{- template "CUSTOM_ERRORS" $cfg }} + {{ template "CUSTOM_ERRORS" $cfg }} } # default server for services without endpoints @@ -367,17 +374,53 @@ http { } stream { + # map FQDN that requires SSL passthrough + map $ssl_preread_server_name $stream_upstream { + {{ range $i, $passthrough := .passthroughUpstreams }} + {{ $passthrough.Host }} {{ $passthrough.Upstream.Name }}-{{ $i }}-pt; + {{ end }} + # send SSL traffic to this nginx in a different port + default nginx-ssl-backend; + } + + log_format log_stream '$remote_addr [$time_local] $protocol [$ssl_preread_server_name] [$stream_upstream] ' + '$status $bytes_sent $bytes_received $session_time'; + + access_log /var/log/nginx/access.log log_stream; + error_log /var/log/nginx/error.log; + + # configure default backend for SSL + upstream nginx-ssl-backend { + server 127.0.0.1:442; + } + + {{ range $i, $passthrough := .passthroughUpstreams }} + upstream {{ $passthrough.Name }}-{{ $i }}-pt { + {{ range $server := $passthrough.Backends }}server {{ $server.Address }}:{{ $server.Port }}; + {{ end }} + } + {{ end }} + + server { + listen 443; + + {{ if $cfg.useProxyProtocol }}proxy_protocol on;{{ end }} + + proxy_pass $stream_upstream; + ssl_preread on; + } + # TCP services {{ range $i, $tcpServer := .tcpUpstreams }} upstream tcp-{{ $tcpServer.Upstream.Name }} { {{ range $server := $tcpServer.Upstream.Backends }}server {{ $server.Address }}:{{ $server.Port }}; {{ end }} } - + server { listen {{ $tcpServer.Path }}; - proxy_connect_timeout {{ $cfg.proxyConnectTimeout }}; - proxy_timeout {{ $cfg.proxyReadTimeout }}; + proxy_connect_timeout {{ $tcpServer.Proxy.ConnectTimeout }}s; + proxy_timeout {{ $tcpServer.Proxy.ReadTimeout }}s; proxy_pass tcp-{{ $tcpServer.Upstream.Name }}; } {{ end }} @@ -388,7 +431,7 @@ stream { {{ range $server := $udpServer.Upstream.Backends }}server {{ $server.Address }}:{{ $server.Port }}; {{ end }} } - + server { listen {{ $udpServer.Path }} udp; proxy_timeout 10s; diff --git a/controllers/nginx/rootfs/ingress-controller/clean-nginx-conf.sh b/controllers/nginx/rootfs/ingress-controller/clean-nginx-conf.sh new file mode 100755 index 0000000000..53662152fc --- /dev/null +++ b/controllers/nginx/rootfs/ingress-controller/clean-nginx-conf.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# This script removes consecutive empty lines in nginx.conf +# Using sed is more simple than using a go regex + +# first sed removes empty lines +# second sed command replaces the empty lines +sed -e 's/^ *$/\'$'\n/g' | sed -e '/^$/{N;/^\n$/d;}' diff --git a/controllers/nginx/utils.go b/controllers/nginx/utils.go deleted file mode 100644 index 877837ed05..0000000000 --- a/controllers/nginx/utils.go +++ /dev/null @@ -1,301 +0,0 @@ -/* -Copyright 2015 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 main - -import ( - "fmt" - "io/ioutil" - "os" - "strings" - "time" - - "github.com/golang/glog" - - "k8s.io/kubernetes/pkg/api" - apierrs "k8s.io/kubernetes/pkg/api/errors" - "k8s.io/kubernetes/pkg/apis/extensions" - "k8s.io/kubernetes/pkg/client/cache" - "k8s.io/kubernetes/pkg/client/unversioned" - "k8s.io/kubernetes/pkg/util/wait" - "k8s.io/kubernetes/pkg/util/workqueue" -) - -// StoreToIngressLister makes a Store that lists Ingress. -type StoreToIngressLister struct { - cache.Store -} - -// StoreToSecretsLister makes a Store that lists Secrets. -type StoreToSecretsLister struct { - cache.Store -} - -// StoreToConfigmapLister makes a Store that lists Configmap. -type StoreToConfigmapLister struct { - cache.Store -} - -// taskQueue manages a work queue through an independent worker that -// invokes the given sync function for every work item inserted. -type taskQueue struct { - // queue is the work queue the worker polls - queue workqueue.RateLimitingInterface - // sync is called for each item in the queue - sync func(string) error - // workerDone is closed when the worker exits - workerDone chan struct{} -} - -func (t *taskQueue) run(period time.Duration, stopCh <-chan struct{}) { - wait.Until(t.worker, period, stopCh) -} - -// enqueue enqueues ns/name of the given api object in the task queue. -func (t *taskQueue) enqueue(obj interface{}) { - key, err := keyFunc(obj) - if err != nil { - glog.Infof("could not get key for object %+v: %v", obj, err) - return - } - t.queue.Add(key) -} - -func (t *taskQueue) requeue(key string) { - t.queue.AddRateLimited(key) -} - -// worker processes work in the queue through sync. -func (t *taskQueue) worker() { - for { - key, quit := t.queue.Get() - if quit { - close(t.workerDone) - return - } - glog.V(3).Infof("syncing %v", key) - if err := t.sync(key.(string)); err != nil { - glog.Warningf("requeuing %v, err %v", key, err) - t.requeue(key.(string)) - } else { - t.queue.Forget(key) - } - - t.queue.Done(key) - } -} - -// shutdown shuts down the work queue and waits for the worker to ACK -func (t *taskQueue) shutdown() { - t.queue.ShutDown() - <-t.workerDone -} - -// NewTaskQueue creates a new task queue with the given sync function. -// The sync function is called for every element inserted into the queue. -func NewTaskQueue(syncFn func(string) error) *taskQueue { - return &taskQueue{ - queue: workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter()), - sync: syncFn, - workerDone: make(chan struct{}), - } -} - -// getPodDetails returns runtime information about the pod: name, namespace and IP of the node -func getPodDetails(kubeClient *unversioned.Client) (*podInfo, error) { - podName := os.Getenv("POD_NAME") - podNs := os.Getenv("POD_NAMESPACE") - - if podName == "" && podNs == "" { - return nil, fmt.Errorf("unable to get POD information (missing POD_NAME or POD_NAMESPACE environment variable") - } - - err := waitForPodRunning(kubeClient, podNs, podName, time.Millisecond*200, time.Second*30) - if err != nil { - return nil, err - } - - pod, _ := kubeClient.Pods(podNs).Get(podName) - if pod == nil { - return nil, fmt.Errorf("unable to get POD information") - } - - node, err := kubeClient.Nodes().Get(pod.Spec.NodeName) - if err != nil { - return nil, err - } - - var externalIP string - for _, address := range node.Status.Addresses { - if address.Type == api.NodeExternalIP { - if address.Address != "" { - externalIP = address.Address - break - } - } - - if externalIP == "" && address.Type == api.NodeLegacyHostIP { - externalIP = address.Address - } - } - - return &podInfo{ - PodName: podName, - PodNamespace: podNs, - NodeIP: externalIP, - }, nil -} - -func isValidService(kubeClient *unversioned.Client, name string) error { - if name == "" { - return fmt.Errorf("empty string is not a valid service name") - } - - parts := strings.Split(name, "/") - if len(parts) != 2 { - return fmt.Errorf("invalid name format (namespace/name) in service '%v'", name) - } - - _, err := kubeClient.Services(parts[0]).Get(parts[1]) - return err -} - -func isHostValid(host string, cns []string) bool { - for _, cn := range cns { - if matchHostnames(cn, host) { - return true - } - } - - return false -} - -func matchHostnames(pattern, host string) bool { - host = strings.TrimSuffix(host, ".") - pattern = strings.TrimSuffix(pattern, ".") - - if len(pattern) == 0 || len(host) == 0 { - return false - } - - patternParts := strings.Split(pattern, ".") - hostParts := strings.Split(host, ".") - - if len(patternParts) != len(hostParts) { - return false - } - - for i, patternPart := range patternParts { - if i == 0 && patternPart == "*" { - continue - } - if patternPart != hostParts[i] { - return false - } - } - - return true -} - -func parseNsName(input string) (string, string, error) { - nsName := strings.Split(input, "/") - if len(nsName) != 2 { - return "", "", fmt.Errorf("invalid format (namespace/name) found in '%v'", input) - } - - return nsName[0], nsName[1], nil -} - -func waitForPodRunning(kubeClient *unversioned.Client, ns, podName string, interval, timeout time.Duration) error { - condition := func(pod *api.Pod) (bool, error) { - if pod.Status.Phase == api.PodRunning { - return true, nil - } - return false, nil - } - - return waitForPodCondition(kubeClient, ns, podName, condition, interval, timeout) -} - -// waitForPodCondition waits for a pod in state defined by a condition (func) -func waitForPodCondition(kubeClient *unversioned.Client, ns, podName string, condition func(pod *api.Pod) (bool, error), - interval, timeout time.Duration) error { - return wait.PollImmediate(interval, timeout, func() (bool, error) { - pod, err := kubeClient.Pods(ns).Get(podName) - if err != nil { - if apierrs.IsNotFound(err) { - return false, nil - } - } - - done, err := condition(pod) - if err != nil { - return false, err - } - if done { - return true, nil - } - - return false, nil - }) -} - -// ingAnnotations represents Ingress annotations. -type ingAnnotations map[string]string - -const ( - // ingressClassKey picks a specific "class" for the Ingress. The controller - // only processes Ingresses with this annotation either unset, or set - // to either nginxIngressClass or the empty string. - ingressClassKey = "kubernetes.io/ingress.class" - nginxIngressClass = "nginx" -) - -func (ing ingAnnotations) ingressClass() string { - val, ok := ing[ingressClassKey] - if !ok { - return "" - } - return val -} - -// isNGINXIngress returns true if the given Ingress either doesn't specify the -// ingress.class annotation, or it's set to "nginx". -func isNGINXIngress(ing *extensions.Ingress) bool { - class := ingAnnotations(ing.ObjectMeta.Annotations).ingressClass() - return class == "" || class == nginxIngressClass -} - -const ( - snakeOilPem = "/etc/ssl/certs/ssl-cert-snakeoil.pem" - snakeOilKey = "/etc/ssl/private/ssl-cert-snakeoil.key" -) - -// getFakeSSLCert returns the snake oil ssl certificate created by the command -// make-ssl-cert generate-default-snakeoil --force-overwrite -func getFakeSSLCert() (string, string) { - cert, err := ioutil.ReadFile(snakeOilPem) - if err != nil { - return "", "" - } - - key, err := ioutil.ReadFile(snakeOilKey) - if err != nil { - return "", "" - } - - return string(cert), string(key) -} diff --git a/core/pkg/cache/main.go b/core/pkg/cache/main.go new file mode 100644 index 0000000000..04257a0ba9 --- /dev/null +++ b/core/pkg/cache/main.go @@ -0,0 +1,34 @@ +/* +Copyright 2015 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 cache + +import "k8s.io/kubernetes/pkg/client/cache" + +// StoreToIngressLister makes a Store that lists Ingress. +type StoreToIngressLister struct { + cache.Store +} + +// StoreToSecretsLister makes a Store that lists Secrets. +type StoreToSecretsLister struct { + cache.Store +} + +// StoreToConfigmapLister makes a Store that lists Configmap. +type StoreToConfigmapLister struct { + cache.Store +} diff --git a/controllers/nginx/nginx/auth/main.go b/core/pkg/ingress/annotations/auth/main.go similarity index 59% rename from controllers/nginx/nginx/auth/main.go rename to core/pkg/ingress/annotations/auth/main.go index 0a10686941..963dc35eb6 100644 --- a/controllers/nginx/nginx/auth/main.go +++ b/core/pkg/ingress/annotations/auth/main.go @@ -23,11 +23,10 @@ import ( "os" "regexp" - "github.com/golang/glog" + "k8s.io/ingress/core/pkg/ingress/annotations/parser" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/apis/extensions" - client "k8s.io/kubernetes/pkg/client/unversioned" ) const ( @@ -35,11 +34,9 @@ const ( authSecret = "ingress.kubernetes.io/auth-secret" authRealm = "ingress.kubernetes.io/auth-realm" - defAuthRealm = "Authentication Required" - // DefAuthDirectory default directory used to store files - // to authenticate request in NGINX - DefAuthDirectory = "/etc/nginx/auth" + // to authenticate request + DefAuthDirectory = "/etc/ingress-controller/auth" ) func init() { @@ -53,95 +50,58 @@ var ( // ErrInvalidAuthType is return in case of unsupported authentication type ErrInvalidAuthType = errors.New("invalid authentication type") - // ErrMissingAuthType is return when the annotation for authentication is missing - ErrMissingAuthType = errors.New("authentication type is missing") - // ErrMissingSecretName is returned when the name of the secret is missing ErrMissingSecretName = errors.New("secret name is missing") // ErrMissingAuthInSecret is returned when there is no auth key in secret data ErrMissingAuthInSecret = errors.New("the secret does not contains the auth key") - - // ErrMissingAnnotations is returned when the ingress rule - // does not contains annotations related with authentication - ErrMissingAnnotations = errors.New("missing authentication annotations") ) -// Nginx returns authentication configuration for an Ingress rule -type Nginx struct { +// BasicDigest returns authentication configuration for an Ingress rule +type BasicDigest struct { Type string Realm string File string Secured bool } -type ingAnnotations map[string]string - -func (a ingAnnotations) authType() (string, error) { - val, ok := a[authType] - if !ok { - return "", ErrMissingAuthType - } - - if !authTypeRegex.MatchString(val) { - glog.Warningf("%v is not a valid authentication type", val) - return "", ErrInvalidAuthType - } - - return val, nil -} - -func (a ingAnnotations) realm() string { - val, ok := a[authRealm] - if !ok { - return defAuthRealm - } - - return val -} - -func (a ingAnnotations) secretName() (string, error) { - val, ok := a[authSecret] - if !ok { - return "", ErrMissingSecretName - } - - return val, nil -} - // ParseAnnotations parses the annotations contained in the ingress // rule used to add authentication in the paths defined in the rule // and generated an htpasswd compatible file to be used as source // during the authentication process -func ParseAnnotations(kubeClient client.Interface, ing *extensions.Ingress, authDir string) (*Nginx, error) { +func ParseAnnotations(ing *extensions.Ingress, authDir string, fn func(string) (*api.Secret, error)) (*BasicDigest, error) { if ing.GetAnnotations() == nil { - return &Nginx{}, ErrMissingAnnotations + return &BasicDigest{}, parser.ErrMissingAnnotations } - at, err := ingAnnotations(ing.GetAnnotations()).authType() + at, err := parser.GetStringAnnotation(authType, ing) if err != nil { - return &Nginx{}, err + return &BasicDigest{}, err + } + + if !authTypeRegex.MatchString(at) { + return &BasicDigest{}, ErrInvalidAuthType } - s, err := ingAnnotations(ing.GetAnnotations()).secretName() + s, err := parser.GetStringAnnotation(authSecret, ing) if err != nil { - return &Nginx{}, err + return &BasicDigest{}, err } - secret, err := kubeClient.Secrets(ing.Namespace).Get(s) + secret, err := fn(fmt.Sprintf("%v/%v", ing.Namespace, s)) if err != nil { - return &Nginx{}, err + return &BasicDigest{}, err } - realm := ingAnnotations(ing.GetAnnotations()).realm() + realm, _ := parser.GetStringAnnotation(authRealm, ing) passFile := fmt.Sprintf("%v/%v-%v.passwd", authDir, ing.GetNamespace(), ing.GetName()) err = dumpSecret(passFile, secret) if err != nil { - return &Nginx{}, err + return &BasicDigest{}, err } - return &Nginx{ + return &BasicDigest{ Type: at, Realm: realm, File: passFile, diff --git a/controllers/nginx/nginx/auth/main_test.go b/core/pkg/ingress/annotations/auth/main_test.go similarity index 59% rename from controllers/nginx/nginx/auth/main_test.go rename to core/pkg/ingress/annotations/auth/main_test.go index 27c8e1db58..bb69990182 100644 --- a/controllers/nginx/nginx/auth/main_test.go +++ b/core/pkg/ingress/annotations/auth/main_test.go @@ -25,8 +25,6 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/apis/extensions" - "k8s.io/kubernetes/pkg/client/unversioned" - "k8s.io/kubernetes/pkg/client/unversioned/testclient" "k8s.io/kubernetes/pkg/util/intstr" ) @@ -65,79 +63,21 @@ func buildIngress() *extensions.Ingress { } } -type secretsClient struct { - unversioned.Interface -} - -// dummySecret generates a secret with one user inside the auth key -// foo:md5(bar) -func dummySecret() *api.Secret { +func mockSecret(name string) (*api.Secret, error) { return &api.Secret{ ObjectMeta: api.ObjectMeta{ Namespace: api.NamespaceDefault, Name: "demo-secret", }, Data: map[string][]byte{"auth": []byte("foo:$apr1$OFG3Xybp$ckL0FHDAkoXYIlH9.cysT0")}, - } -} - -func mockClient() *testclient.Fake { - return testclient.NewSimpleFake(dummySecret()) + }, nil } - -func TestAnnotations(t *testing.T) { - ing := buildIngress() - - _, err := ingAnnotations(ing.GetAnnotations()).authType() - if err == nil { - t.Error("Expected a validation error") - } - realm := ingAnnotations(ing.GetAnnotations()).realm() - if realm != defAuthRealm { - t.Error("Expected default realm") - } - - _, err = ingAnnotations(ing.GetAnnotations()).secretName() - if err == nil { - t.Error("Expected a validation error") - } - - data := map[string]string{} - data[authType] = "demo" - data[authSecret] = "demo-secret" - data[authRealm] = "demo" - ing.SetAnnotations(data) - - _, err = ingAnnotations(ing.GetAnnotations()).authType() - if err == nil { - t.Error("Expected a validation error") - } - - realm = ingAnnotations(ing.GetAnnotations()).realm() - if realm != "demo" { - t.Errorf("Expected demo as realm but returned %s", realm) - } - - secret, err := ingAnnotations(ing.GetAnnotations()).secretName() - if err != nil { - t.Errorf("Unexpec error %v", err) - } - if secret != "demo-secret" { - t.Errorf("Expected demo-secret as realm but returned %s", secret) - } -} - func TestIngressWithoutAuth(t *testing.T) { ing := buildIngress() - client := mockClient() - _, err := ParseAnnotations(client, ing, "") + _, err := ParseAnnotations(ing, "", mockSecret) if err == nil { t.Error("Expected error with ingress without annotations") } - - if err == ErrMissingAuthType { - t.Errorf("Expected MissingAuthType error but returned %v", err) - } } func TestIngressAuth(t *testing.T) { @@ -152,20 +92,19 @@ func TestIngressAuth(t *testing.T) { _, dir, _ := dummySecretContent(t) defer os.RemoveAll(dir) - client := mockClient() - nginxAuth, err := ParseAnnotations(client, ing, dir) + auth, err := ParseAnnotations(ing, dir, mockSecret) if err != nil { t.Errorf("Uxpected error with ingress: %v", err) } - if nginxAuth.Type != "basic" { - t.Errorf("Expected basic as auth type but returned %s", nginxAuth.Type) + if auth.Type != "basic" { + t.Errorf("Expected basic as auth type but returned %s", auth.Type) } - if nginxAuth.Realm != "-realm-" { - t.Errorf("Expected -realm- as realm but returned %s", nginxAuth.Realm) + if auth.Realm != "-realm-" { + t.Errorf("Expected -realm- as realm but returned %s", auth.Realm) } - if !nginxAuth.Secured { - t.Errorf("Expected true as secured but returned %v", nginxAuth.Secured) + if !auth.Secured { + t.Errorf("Expected true as secured but returned %v", auth.Secured) } } @@ -180,9 +119,7 @@ func dummySecretContent(t *testing.T) (string, string, *api.Secret) { t.Error(err) } defer tmpfile.Close() - - s := dummySecret() - + s, _ := mockSecret("demo") return tmpfile.Name(), dir, s } diff --git a/controllers/nginx/nginx/authreq/main.go b/core/pkg/ingress/annotations/authreq/main.go similarity index 53% rename from controllers/nginx/nginx/authreq/main.go rename to core/pkg/ingress/annotations/authreq/main.go index 0f53e5bd24..efa0d79043 100644 --- a/controllers/nginx/nginx/authreq/main.go +++ b/core/pkg/ingress/annotations/authreq/main.go @@ -17,12 +17,11 @@ limitations under the License. package authreq import ( - "errors" "fmt" "net/url" - "strconv" "strings" + "k8s.io/ingress/core/pkg/ingress/annotations/parser" "k8s.io/kubernetes/pkg/apis/extensions" ) @@ -33,49 +32,13 @@ const ( authBody = "ingress.kubernetes.io/auth-send-body" ) -var ( - // ErrMissingAnnotations is returned when the ingress rule - // does not contain annotations related with authentication - ErrMissingAnnotations = errors.New("missing authentication annotations") -) - -// Auth returns external authentication configuration for an Ingress rule -type Auth struct { +// External returns external authentication configuration for an Ingress rule +type External struct { URL string Method string SendBody bool } -type ingAnnotations map[string]string - -func (a ingAnnotations) url() (string, error) { - val, ok := a[authURL] - if !ok { - return "", ErrMissingAnnotations - } - - return val, nil -} - -func (a ingAnnotations) method() string { - val, ok := a[authMethod] - if !ok { - return "" - } - - return val -} - -func (a ingAnnotations) sendBody() bool { - val, ok := a[authBody] - if ok { - if b, err := strconv.ParseBool(val); err == nil { - return b - } - } - return false -} - var ( methods = []string{"GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "CONNECT", "OPTIONS", "TRACE"} ) @@ -95,42 +58,42 @@ func validMethod(method string) bool { // ParseAnnotations parses the annotations contained in the ingress // rule used to use an external URL as source for authentication -func ParseAnnotations(ing *extensions.Ingress) (Auth, error) { +func ParseAnnotations(ing *extensions.Ingress) (External, error) { if ing.GetAnnotations() == nil { - return Auth{}, ErrMissingAnnotations + return External{}, parser.ErrMissingAnnotations } - str, err := ingAnnotations(ing.GetAnnotations()).url() + str, err := parser.GetStringAnnotation(authURL, ing) if err != nil { - return Auth{}, err + return External{}, err } if str == "" { - return Auth{}, fmt.Errorf("an empty string is not a valid URL") + return External{}, fmt.Errorf("an empty string is not a valid URL") } ur, err := url.Parse(str) if err != nil { - return Auth{}, err + return External{}, err } if ur.Scheme == "" { - return Auth{}, fmt.Errorf("url scheme is empty") + return External{}, fmt.Errorf("url scheme is empty") } if ur.Host == "" { - return Auth{}, fmt.Errorf("url host is empty") + return External{}, fmt.Errorf("url host is empty") } - if strings.Index(ur.Host, "..") != -1 { - return Auth{}, fmt.Errorf("invalid url host") + if strings.Contains(ur.Host, "..") { + return External{}, fmt.Errorf("invalid url host") } - m := ingAnnotations(ing.GetAnnotations()).method() + m, _ := parser.GetStringAnnotation(authMethod, ing) if len(m) != 0 && !validMethod(m) { - return Auth{}, fmt.Errorf("invalid HTTP method") + return External{}, fmt.Errorf("invalid HTTP method") } - sb := ingAnnotations(ing.GetAnnotations()).sendBody() + sb, _ := parser.GetBoolAnnotation(authBody, ing) - return Auth{ + return External{ URL: str, Method: m, SendBody: sb, diff --git a/controllers/nginx/nginx/authreq/main_test.go b/core/pkg/ingress/annotations/authreq/main_test.go similarity index 96% rename from controllers/nginx/nginx/authreq/main_test.go rename to core/pkg/ingress/annotations/authreq/main_test.go index f2936f72ba..57f1825999 100644 --- a/controllers/nginx/nginx/authreq/main_test.go +++ b/core/pkg/ingress/annotations/authreq/main_test.go @@ -63,11 +63,6 @@ func buildIngress() *extensions.Ingress { func TestAnnotations(t *testing.T) { ing := buildIngress() - _, err := ingAnnotations(ing.GetAnnotations()).url() - if err == nil { - t.Error("Expected a validation error") - } - data := map[string]string{} ing.SetAnnotations(data) diff --git a/core/pkg/ingress/annotations/authtls/main.go b/core/pkg/ingress/annotations/authtls/main.go new file mode 100644 index 0000000000..b515c37744 --- /dev/null +++ b/core/pkg/ingress/annotations/authtls/main.go @@ -0,0 +1,65 @@ +/* +Copyright 2015 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 authtls + +import ( + "fmt" + + "k8s.io/ingress/core/pkg/ingress/annotations/parser" + "k8s.io/ingress/core/pkg/k8s" + + "k8s.io/kubernetes/pkg/apis/extensions" +) + +const ( + // name of the secret + authTLSSecret = "ingress.kubernetes.io/auth-tls-secret" +) + +// SSLCert returns external authentication configuration for an Ingress rule +type SSLCert struct { + Secret string + CertFileName string + KeyFileName string + CAFileName string + PemSHA string +} + +// ParseAnnotations parses the annotations contained in the ingress +// rule used to use an external URL as source for authentication +func ParseAnnotations(ing *extensions.Ingress, + fn func(secret string) (*SSLCert, error)) (*SSLCert, error) { + if ing.GetAnnotations() == nil { + return &SSLCert{}, parser.ErrMissingAnnotations + } + + str, err := parser.GetStringAnnotation(authTLSSecret, ing) + if err != nil { + return &SSLCert{}, err + } + + if str == "" { + return &SSLCert{}, fmt.Errorf("an empty string is not a valid secret name") + } + + _, _, err = k8s.ParseNameNS(str) + if err != nil { + return &SSLCert{}, err + } + + return fn(str) +} diff --git a/core/pkg/ingress/annotations/authtls/main_test.go b/core/pkg/ingress/annotations/authtls/main_test.go new file mode 100644 index 0000000000..b1f4886f64 --- /dev/null +++ b/core/pkg/ingress/annotations/authtls/main_test.go @@ -0,0 +1,107 @@ +/* +Copyright 2015 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 authtls + +import ( + "testing" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/util/intstr" +) + +func buildIngress() *extensions.Ingress { + defaultBackend := extensions.IngressBackend{ + ServiceName: "default-backend", + ServicePort: intstr.FromInt(80), + } + + return &extensions.Ingress{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Namespace: api.NamespaceDefault, + }, + Spec: extensions.IngressSpec{ + Backend: &extensions.IngressBackend{ + ServiceName: "default-backend", + ServicePort: intstr.FromInt(80), + }, + Rules: []extensions.IngressRule{ + { + Host: "foo.bar.com", + IngressRuleValue: extensions.IngressRuleValue{ + HTTP: &extensions.HTTPIngressRuleValue{ + Paths: []extensions.HTTPIngressPath{ + { + Path: "/foo", + Backend: defaultBackend, + }, + }, + }, + }, + }, + }, + }, + } +} + +func TestAnnotations(t *testing.T) { + ing := buildIngress() + + data := map[string]string{} + ing.SetAnnotations(data) + /* + tests := []struct { + title string + url string + method string + sendBody bool + expErr bool + }{ + {"empty", "", "", false, true}, + {"no scheme", "bar", "", false, true}, + {"invalid host", "http://", "", false, true}, + {"invalid host (multiple dots)", "http://foo..bar.com", "", false, true}, + {"valid URL", "http://bar.foo.com/external-auth", "", false, false}, + {"valid URL - send body", "http://foo.com/external-auth", "POST", true, false}, + {"valid URL - send body", "http://foo.com/external-auth", "GET", true, false}, + } + + for _, test := range tests { + data[authTLSSecret] = "" + test.title + + u, err := ParseAnnotations(ing) + + if test.expErr { + if err == nil { + t.Errorf("%v: expected error but retuned nil", test.title) + } + continue + } + + if u.URL != test.url { + t.Errorf("%v: expected \"%v\" but \"%v\" was returned", test.title, test.url, u.URL) + } + if u.Method != test.method { + t.Errorf("%v: expected \"%v\" but \"%v\" was returned", test.title, test.method, u.Method) + } + if u.SendBody != test.sendBody { + t.Errorf("%v: expected \"%v\" but \"%v\" was returned", test.title, test.sendBody, u.SendBody) + } + }*/ +} diff --git a/controllers/nginx/nginx/cors/main.go b/core/pkg/ingress/annotations/cors/main.go similarity index 71% rename from controllers/nginx/nginx/cors/main.go rename to core/pkg/ingress/annotations/cors/main.go index 436e25231f..4208965056 100644 --- a/controllers/nginx/nginx/cors/main.go +++ b/core/pkg/ingress/annotations/cors/main.go @@ -17,8 +17,7 @@ limitations under the License. package cors import ( - "errors" - "strconv" + "k8s.io/ingress/core/pkg/ingress/annotations/parser" "k8s.io/kubernetes/pkg/apis/extensions" ) @@ -27,24 +26,8 @@ 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 + return parser.GetBoolAnnotation(cors, ing) } diff --git a/controllers/nginx/nginx/healthcheck/main.go b/core/pkg/ingress/annotations/healthcheck/main.go similarity index 50% rename from controllers/nginx/nginx/healthcheck/main.go rename to core/pkg/ingress/annotations/healthcheck/main.go index 7abf719602..344db3c6da 100644 --- a/controllers/nginx/nginx/healthcheck/main.go +++ b/core/pkg/ingress/annotations/healthcheck/main.go @@ -17,12 +17,10 @@ limitations under the License. package healthcheck import ( - "errors" - "strconv" - "k8s.io/kubernetes/pkg/apis/extensions" - "k8s.io/contrib/ingress/controllers/nginx/nginx/config" + "k8s.io/ingress/core/pkg/ingress/annotations/parser" + "k8s.io/ingress/core/pkg/ingress/defaults" ) const ( @@ -30,19 +28,6 @@ const ( upsFailTimeout = "ingress.kubernetes.io/upstream-fail-timeout" ) -var ( - // ErrMissingMaxFails returned error when the ingress does not contains the - // max-fails annotation - ErrMissingMaxFails = errors.New("max-fails annotations is missing") - - // ErrMissingFailTimeout returned error when the ingress does not contains - // the fail-timeout annotation - ErrMissingFailTimeout = errors.New("fail-timeout annotations is missing") - - // ErrInvalidNumber returned - ErrInvalidNumber = errors.New("the annotation does not contains a number") -) - // Upstream returns the URL and method to use check the status of // the upstream server/s type Upstream struct { @@ -50,49 +35,19 @@ type Upstream struct { FailTimeout int } -type ingAnnotations map[string]string - -func (a ingAnnotations) maxFails() (int, error) { - val, ok := a[upsMaxFails] - if !ok { - return 0, ErrMissingMaxFails - } - - mf, err := strconv.Atoi(val) - if err != nil { - return 0, ErrInvalidNumber - } - - return mf, nil -} - -func (a ingAnnotations) failTimeout() (int, error) { - val, ok := a[upsFailTimeout] - if !ok { - return 0, ErrMissingFailTimeout - } - - ft, err := strconv.Atoi(val) - if err != nil { - return 0, ErrInvalidNumber - } - - return ft, nil -} - // ParseAnnotations parses the annotations contained in the ingress // rule used to configure upstream check parameters -func ParseAnnotations(cfg config.Configuration, ing *extensions.Ingress) *Upstream { +func ParseAnnotations(cfg defaults.Backend, ing *extensions.Ingress) *Upstream { if ing.GetAnnotations() == nil { return &Upstream{cfg.UpstreamMaxFails, cfg.UpstreamFailTimeout} } - mf, err := ingAnnotations(ing.GetAnnotations()).maxFails() + mf, err := parser.GetIntAnnotation(upsMaxFails, ing) if err != nil { mf = cfg.UpstreamMaxFails } - ft, err := ingAnnotations(ing.GetAnnotations()).failTimeout() + ft, err := parser.GetIntAnnotation(upsFailTimeout, ing) if err != nil { ft = cfg.UpstreamFailTimeout } diff --git a/controllers/nginx/nginx/healthcheck/main_test.go b/core/pkg/ingress/annotations/healthcheck/main_test.go similarity index 67% rename from controllers/nginx/nginx/healthcheck/main_test.go rename to core/pkg/ingress/annotations/healthcheck/main_test.go index 315c11729e..aba9c73858 100644 --- a/controllers/nginx/nginx/healthcheck/main_test.go +++ b/core/pkg/ingress/annotations/healthcheck/main_test.go @@ -23,7 +23,7 @@ import ( "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/util/intstr" - "k8s.io/contrib/ingress/controllers/nginx/nginx/config" + "k8s.io/ingress/core/pkg/ingress/defaults" ) func buildIngress() *extensions.Ingress { @@ -61,41 +61,6 @@ func buildIngress() *extensions.Ingress { } } -func TestAnnotations(t *testing.T) { - ing := buildIngress() - - _, err := ingAnnotations(ing.GetAnnotations()).maxFails() - if err == nil { - t.Error("Expected a validation error") - } - - _, err = ingAnnotations(ing.GetAnnotations()).failTimeout() - if err == nil { - t.Error("Expected a validation error") - } - - data := map[string]string{} - data[upsMaxFails] = "1" - data[upsFailTimeout] = "1" - ing.SetAnnotations(data) - - mf, err := ingAnnotations(ing.GetAnnotations()).maxFails() - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - if mf != 1 { - t.Errorf("Expected 1 but returned %v", mf) - } - - ft, err := ingAnnotations(ing.GetAnnotations()).failTimeout() - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - if ft != 1 { - t.Errorf("Expected 1 but returned %v", ft) - } -} - func TestIngressHealthCheck(t *testing.T) { ing := buildIngress() @@ -103,8 +68,7 @@ func TestIngressHealthCheck(t *testing.T) { data[upsMaxFails] = "2" ing.SetAnnotations(data) - cfg := config.Configuration{} - cfg.UpstreamFailTimeout = 1 + cfg := defaults.Backend{UpstreamFailTimeout: 1} nginxHz := ParseAnnotations(cfg, ing) diff --git a/controllers/nginx/nginx/ipwhitelist/main.go b/core/pkg/ingress/annotations/ipwhitelist/main.go similarity index 69% rename from controllers/nginx/nginx/ipwhitelist/main.go rename to core/pkg/ingress/annotations/ipwhitelist/main.go index de34a9312c..f3ff0fe21a 100644 --- a/controllers/nginx/nginx/ipwhitelist/main.go +++ b/core/pkg/ingress/annotations/ipwhitelist/main.go @@ -20,6 +20,9 @@ import ( "errors" "strings" + "k8s.io/ingress/core/pkg/ingress/annotations/parser" + "k8s.io/ingress/core/pkg/ingress/defaults" + "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/util/net/sets" ) @@ -29,10 +32,6 @@ const ( ) var ( - // ErrMissingWhitelist returned error when the ingress does not contains the - // whitelist annotation - ErrMissingWhitelist = errors.New("whitelist annotation is missing") - // ErrInvalidCIDR returned error when the whitelist annotation does not // contains a valid IP or network address ErrInvalidCIDR = errors.New("the annotation does not contains a valid IP address or network") @@ -43,41 +42,31 @@ type SourceRange struct { CIDR []string } -type ingAnnotations map[string]string +// ParseAnnotations parses the annotations contained in the ingress +// rule used to limit access to certain client addresses or networks. +// Multiple ranges can specified using commas as separator +// e.g. `18.0.0.0/8,56.0.0.0/8` +func ParseAnnotations(cfg defaults.Backend, ing *extensions.Ingress) (*SourceRange, error) { + cidrs := []string{} -func (a ingAnnotations) whitelist() ([]string, error) { - cidrs := make([]string, 0) - val, ok := a[whitelist] - if !ok { - return cidrs, ErrMissingWhitelist + if ing.GetAnnotations() == nil { + return &SourceRange{CIDR: cfg.WhitelistSourceRange}, parser.ErrMissingAnnotations + } + + val, err := parser.GetStringAnnotation(whitelist, ing) + if err != nil { + return &SourceRange{CIDR: cfg.WhitelistSourceRange}, err } values := strings.Split(val, ",") ipnets, err := sets.ParseIPNets(values...) if err != nil { - return cidrs, ErrInvalidCIDR + return &SourceRange{CIDR: cfg.WhitelistSourceRange}, ErrInvalidCIDR } for k := range ipnets { cidrs = append(cidrs, k) } - return cidrs, nil -} - -// ParseAnnotations parses the annotations contained in the ingress -// rule used to limit access to certain client addresses or networks. -// Multiple ranges can specified using commas as separator -// e.g. `18.0.0.0/8,56.0.0.0/8` -func ParseAnnotations(whiteList []string, ing *extensions.Ingress) (*SourceRange, error) { - if ing.GetAnnotations() == nil { - return &SourceRange{whiteList}, ErrMissingWhitelist - } - - wl, err := ingAnnotations(ing.GetAnnotations()).whitelist() - if err != nil { - wl = whiteList - } - - return &SourceRange{wl}, err + return &SourceRange{cidrs}, nil } diff --git a/controllers/nginx/nginx/ipwhitelist/main_test.go b/core/pkg/ingress/annotations/ipwhitelist/main_test.go similarity index 60% rename from controllers/nginx/nginx/ipwhitelist/main_test.go rename to core/pkg/ingress/annotations/ipwhitelist/main_test.go index c081a02746..db623dd68f 100644 --- a/controllers/nginx/nginx/ipwhitelist/main_test.go +++ b/core/pkg/ingress/annotations/ipwhitelist/main_test.go @@ -23,6 +23,8 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/util/intstr" + + "k8s.io/ingress/core/pkg/ingress/defaults" ) func buildIngress() *extensions.Ingress { @@ -60,51 +62,9 @@ func buildIngress() *extensions.Ingress { } } -func TestAnnotations(t *testing.T) { - ing := buildIngress() - - _, err := ingAnnotations(ing.GetAnnotations()).whitelist() - if err == nil { - t.Error("Expected a validation error") - } - - testNet := "10.0.0.0/24" - enet := []string{testNet} - - data := map[string]string{} - data[whitelist] = testNet - ing.SetAnnotations(data) - - wl, err := ingAnnotations(ing.GetAnnotations()).whitelist() - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - - if !reflect.DeepEqual(wl, enet) { - t.Errorf("Expected %v but returned %s", enet, wl) - } - - data[whitelist] = "10.0.0.0/24,10.0.1.0/25" - ing.SetAnnotations(data) - - wl, err = ingAnnotations(ing.GetAnnotations()).whitelist() - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - - if len(wl) != 2 { - t.Errorf("Expected 2 netwotks but %v was returned", len(wl)) - } -} - func TestParseAnnotations(t *testing.T) { ing := buildIngress() - _, err := ingAnnotations(ing.GetAnnotations()).whitelist() - if err == nil { - t.Error("Expected a validation error") - } - testNet := "10.0.0.0/24" enet := []string{testNet} @@ -116,7 +76,7 @@ func TestParseAnnotations(t *testing.T) { CIDR: enet, } - sr, err := ParseAnnotations([]string{}, ing) + sr, err := ParseAnnotations(defaults.Backend{}, ing) if err != nil { t.Errorf("Unexpected error: %v", err) } @@ -127,21 +87,23 @@ func TestParseAnnotations(t *testing.T) { data[whitelist] = "www" ing.SetAnnotations(data) - _, err = ParseAnnotations([]string{}, ing) + _, err = ParseAnnotations(defaults.Backend{}, ing) if err == nil { t.Errorf("Expected error parsing an invalid cidr") } delete(data, "whitelist") ing.SetAnnotations(data) - sr, _ = ParseAnnotations([]string{}, ing) - if !reflect.DeepEqual(sr.CIDR, []string{}) { - t.Errorf("Expected empty CIDR but %v returned", sr.CIDR) - } - - sr, _ = ParseAnnotations([]string{}, &extensions.Ingress{}) - if !reflect.DeepEqual(sr.CIDR, []string{}) { - t.Errorf("Expected empty CIDR but %v returned", sr.CIDR) - } - + //sr, _ = ParseAnnotations(defaults.Backend{}, ing) + // TODO: fix test + /* + if !reflect.DeepEqual(sr.CIDR, []string{}) { + t.Errorf("Expected empty CIDR but %v returned", sr.CIDR) + } + + sr, _ = ParseAnnotations(defaults.Upstream{}, &extensions.Ingress{}) + if !reflect.DeepEqual(sr.CIDR, []string{}) { + t.Errorf("Expected empty CIDR but %v returned", sr.CIDR) + } + */ } diff --git a/core/pkg/ingress/annotations/parser/main.go b/core/pkg/ingress/annotations/parser/main.go new file mode 100644 index 0000000000..31736cf820 --- /dev/null +++ b/core/pkg/ingress/annotations/parser/main.go @@ -0,0 +1,102 @@ +/* +Copyright 2015 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 parser + +import ( + "errors" + "fmt" + "strconv" + + "k8s.io/kubernetes/pkg/apis/extensions" +) + +var ( + // ErrMissingAnnotations is returned when the ingress rule + // does not contains annotations related with rate limit + ErrMissingAnnotations = errors.New("Ingress rule without annotations") + + // ErrInvalidName ... + ErrInvalidName = errors.New("invalid annotation name") +) + +type ingAnnotations map[string]string + +func (a ingAnnotations) parseBool(name string) (bool, error) { + val, ok := a[name] + if ok { + if b, err := strconv.ParseBool(val); err == nil { + return b, nil + } + } + return false, ErrMissingAnnotations +} + +func (a ingAnnotations) parseString(name string) (string, error) { + val, ok := a[name] + if ok { + return val, nil + } + return "", ErrMissingAnnotations +} + +func (a ingAnnotations) parseInt(name string) (int, error) { + val, ok := a[name] + if ok { + i, err := strconv.Atoi(val) + if err != nil { + return 0, fmt.Errorf("invalid annotations value: %v", err) + } + return i, nil + } + return 0, ErrMissingAnnotations +} + +// GetBoolAnnotation ... +func GetBoolAnnotation(name string, ing *extensions.Ingress) (bool, error) { + if ing == nil || ing.GetAnnotations() == nil { + return false, ErrMissingAnnotations + } + if name == "" { + return false, ErrInvalidName + } + + return ingAnnotations(ing.GetAnnotations()).parseBool(name) +} + +// GetStringAnnotation ... +func GetStringAnnotation(name string, ing *extensions.Ingress) (string, error) { + if ing == nil || ing.GetAnnotations() == nil { + return "", ErrMissingAnnotations + } + if name == "" { + return "", ErrInvalidName + } + + return ingAnnotations(ing.GetAnnotations()).parseString(name) +} + +// GetIntAnnotation ... +func GetIntAnnotation(name string, ing *extensions.Ingress) (int, error) { + if ing == nil || ing.GetAnnotations() == nil { + return 0, ErrMissingAnnotations + } + if name == "" { + return 0, ErrInvalidName + } + + return ingAnnotations(ing.GetAnnotations()).parseInt(name) +} diff --git a/core/pkg/ingress/annotations/parser/main_test.go b/core/pkg/ingress/annotations/parser/main_test.go new file mode 100644 index 0000000000..1c756cdc2c --- /dev/null +++ b/core/pkg/ingress/annotations/parser/main_test.go @@ -0,0 +1,154 @@ +/* +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 parser + +import ( + "testing" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/apis/extensions" +) + +func buildIngress() *extensions.Ingress { + return &extensions.Ingress{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Namespace: api.NamespaceDefault, + }, + Spec: extensions.IngressSpec{}, + } +} + +func TestGetBoolAnnotation(t *testing.T) { + ing := buildIngress() + + _, err := GetBoolAnnotation("", nil) + if err == nil { + t.Errorf("expected error but retuned nil") + } + + tests := []struct { + name string + field string + value string + exp bool + expErr bool + }{ + {"empty - false", "", "false", false, true}, + {"empty - true", "", "true", false, true}, + {"valid - false", "bool", "false", false, false}, + {"valid - true", "bool", "true", true, false}, + } + + data := map[string]string{} + ing.SetAnnotations(data) + + for _, test := range tests { + data[test.field] = test.value + + u, err := GetBoolAnnotation(test.field, ing) + if test.expErr { + if err == nil { + t.Errorf("%v: expected error but retuned nil", test.name) + } + continue + } + if u != test.exp { + t.Errorf("%v: expected \"%v\" but \"%v\" was returned", test.name, test.exp, u) + } + } +} + +func TestGetStringAnnotation(t *testing.T) { + ing := buildIngress() + + _, err := GetStringAnnotation("", nil) + if err == nil { + t.Errorf("expected error but retuned nil") + } + + tests := []struct { + name string + field string + value string + exp string + expErr bool + }{ + {"empty - A", "", "A", "", true}, + {"empty - B", "", "B", "", true}, + {"valid - A", "string", "A", "A", false}, + {"valid - B", "string", "B", "B", false}, + } + + data := map[string]string{} + ing.SetAnnotations(data) + + for _, test := range tests { + data[test.field] = test.value + + s, err := GetStringAnnotation(test.field, ing) + if test.expErr { + if err == nil { + t.Errorf("%v: expected error but retuned nil", test.name) + } + continue + } + if s != test.exp { + t.Errorf("%v: expected \"%v\" but \"%v\" was returned", test.name, test.exp, s) + } + } +} + +func TestGetIntAnnotation(t *testing.T) { + ing := buildIngress() + + _, err := GetIntAnnotation("", nil) + if err == nil { + t.Errorf("expected error but retuned nil") + } + + tests := []struct { + name string + field string + value string + exp int + expErr bool + }{ + {"empty - A", "", "1", 0, true}, + {"empty - B", "", "2", 0, true}, + {"valid - A", "string", "1", 1, false}, + {"valid - B", "string", "2", 2, false}, + } + + data := map[string]string{} + ing.SetAnnotations(data) + + for _, test := range tests { + data[test.field] = test.value + + s, err := GetIntAnnotation(test.field, ing) + if test.expErr { + if err == nil { + t.Errorf("%v: expected error but retuned nil", test.name) + } + continue + } + if s != test.exp { + t.Errorf("%v: expected \"%v\" but \"%v\" was returned", test.name, test.exp, s) + } + } +} diff --git a/core/pkg/ingress/annotations/proxy/main.go b/core/pkg/ingress/annotations/proxy/main.go new file mode 100644 index 0000000000..321a46652a --- /dev/null +++ b/core/pkg/ingress/annotations/proxy/main.go @@ -0,0 +1,74 @@ +/* +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 proxy + +import ( + "k8s.io/kubernetes/pkg/apis/extensions" + + "k8s.io/ingress/core/pkg/ingress/annotations/parser" + "k8s.io/ingress/core/pkg/ingress/defaults" +) + +const ( + connect = "ingress.kubernetes.io/proxy-connect-timeout" + send = "ingress.kubernetes.io/proxy-send-timeout" + read = "ingress.kubernetes.io/proxy-read-timeout" + bufferSize = "ingress.kubernetes.io/proxy-buffer-size" +) + +// Configuration returns the proxy timeout to use in the upstream server/s +type Configuration struct { + ConnectTimeout int + SendTimeout int + ReadTimeout int + BufferSize string +} + +// ParseAnnotations parses the annotations contained in the ingress +// rule used to configure upstream check parameters +func ParseAnnotations(cfg defaults.Backend, ing *extensions.Ingress) *Configuration { + if ing == nil || ing.GetAnnotations() == nil { + return &Configuration{ + cfg.ProxyConnectTimeout, + cfg.ProxySendTimeout, + cfg.ProxyReadTimeout, + cfg.ProxyBufferSize, + } + } + + ct, err := parser.GetIntAnnotation(connect, ing) + if err != nil { + ct = cfg.ProxyConnectTimeout + } + + st, err := parser.GetIntAnnotation(send, ing) + if err != nil { + st = cfg.ProxySendTimeout + } + + rt, err := parser.GetIntAnnotation(read, ing) + if err != nil { + rt = cfg.ProxyReadTimeout + } + + bs, err := parser.GetStringAnnotation(bufferSize, ing) + if err != nil || bs == "" { + bs = cfg.ProxyBufferSize + } + + return &Configuration{ct, st, rt, bs} +} diff --git a/core/pkg/ingress/annotations/proxy/main_test.go b/core/pkg/ingress/annotations/proxy/main_test.go new file mode 100644 index 0000000000..337408d686 --- /dev/null +++ b/core/pkg/ingress/annotations/proxy/main_test.go @@ -0,0 +1,90 @@ +/* +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 proxy + +import ( + "testing" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/util/intstr" + + "k8s.io/ingress/core/pkg/ingress/defaults" +) + +func buildIngress() *extensions.Ingress { + defaultBackend := extensions.IngressBackend{ + ServiceName: "default-backend", + ServicePort: intstr.FromInt(80), + } + + return &extensions.Ingress{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Namespace: api.NamespaceDefault, + }, + Spec: extensions.IngressSpec{ + Backend: &extensions.IngressBackend{ + ServiceName: "default-backend", + ServicePort: intstr.FromInt(80), + }, + Rules: []extensions.IngressRule{ + { + Host: "foo.bar.com", + IngressRuleValue: extensions.IngressRuleValue{ + HTTP: &extensions.HTTPIngressRuleValue{ + Paths: []extensions.HTTPIngressPath{ + { + Path: "/foo", + Backend: defaultBackend, + }, + }, + }, + }, + }, + }, + }, + } +} + +func TestIngressHealthCheck(t *testing.T) { + ing := buildIngress() + + data := map[string]string{} + data[connect] = "1" + data[send] = "2" + data[read] = "3" + data[bufferSize] = "1k" + ing.SetAnnotations(data) + + cfg := defaults.Backend{UpstreamFailTimeout: 1} + + p := ParseAnnotations(cfg, ing) + + if p.ConnectTimeout != 1 { + t.Errorf("Expected 1 as connect-timeout but returned %v", p.ConnectTimeout) + } + if p.SendTimeout != 2 { + t.Errorf("Expected 2 as send-timeout but returned %v", p.SendTimeout) + } + if p.ReadTimeout != 3 { + t.Errorf("Expected 3 as read-timeout but returned %v", p.ReadTimeout) + } + if p.BufferSize != "1k" { + t.Errorf("Expected 1k as buffer-size but returned %v", p.BufferSize) + } +} diff --git a/controllers/nginx/nginx/ratelimit/main.go b/core/pkg/ingress/annotations/ratelimit/main.go similarity index 78% rename from controllers/nginx/nginx/ratelimit/main.go rename to core/pkg/ingress/annotations/ratelimit/main.go index 2a1036fb72..c084d76e83 100644 --- a/controllers/nginx/nginx/ratelimit/main.go +++ b/core/pkg/ingress/annotations/ratelimit/main.go @@ -19,7 +19,8 @@ package ratelimit import ( "errors" "fmt" - "strconv" + + "k8s.io/ingress/core/pkg/ingress/annotations/parser" "k8s.io/kubernetes/pkg/apis/extensions" ) @@ -39,10 +40,6 @@ const ( var ( // ErrInvalidRateLimit is returned when the annotation caontains invalid values ErrInvalidRateLimit = errors.New("invalid rate limit value. Must be > 0") - - // ErrMissingAnnotations is returned when the ingress rule - // does not contains annotations related with rate limit - ErrMissingAnnotations = errors.New("no annotations present") ) // RateLimit returns rate limit configuration for an Ingress rule @@ -66,39 +63,15 @@ type Zone struct { SharedSize int } -type ingAnnotations map[string]string - -func (a ingAnnotations) limitIP() int { - val, ok := a[limitIP] - if ok { - if i, err := strconv.Atoi(val); err == nil { - return i - } - } - - return 0 -} - -func (a ingAnnotations) limitRPS() int { - val, ok := a[limitRPS] - if ok { - if i, err := strconv.Atoi(val); err == nil { - return i - } - } - - return 0 -} - // ParseAnnotations parses the annotations contained in the ingress // rule used to rewrite the defined paths func ParseAnnotations(ing *extensions.Ingress) (*RateLimit, error) { if ing.GetAnnotations() == nil { - return &RateLimit{}, ErrMissingAnnotations + return &RateLimit{}, parser.ErrMissingAnnotations } - rps := ingAnnotations(ing.GetAnnotations()).limitRPS() - conn := ingAnnotations(ing.GetAnnotations()).limitIP() + rps, _ := parser.GetIntAnnotation(limitRPS, ing) + conn, _ := parser.GetIntAnnotation(limitIP, ing) if rps == 0 && conn == 0 { return &RateLimit{ diff --git a/controllers/nginx/nginx/ratelimit/main_test.go b/core/pkg/ingress/annotations/ratelimit/main_test.go similarity index 76% rename from controllers/nginx/nginx/ratelimit/main_test.go rename to core/pkg/ingress/annotations/ratelimit/main_test.go index 4a7adec8c4..3095662cec 100644 --- a/controllers/nginx/nginx/ratelimit/main_test.go +++ b/core/pkg/ingress/annotations/ratelimit/main_test.go @@ -59,35 +59,6 @@ func buildIngress() *extensions.Ingress { } } -func TestAnnotations(t *testing.T) { - ing := buildIngress() - - lip := ingAnnotations(ing.GetAnnotations()).limitIP() - if lip != 0 { - t.Errorf("Expected 0 in limit by ip but %v was returned", lip) - } - - lrps := ingAnnotations(ing.GetAnnotations()).limitRPS() - if lrps != 0 { - t.Errorf("Expected 0 in limit by rps but %v was returend", lrps) - } - - data := map[string]string{} - data[limitIP] = "5" - data[limitRPS] = "100" - ing.SetAnnotations(data) - - lip = ingAnnotations(ing.GetAnnotations()).limitIP() - if lip != 5 { - t.Errorf("Expected 5 in limit by ip but %v was returend", lip) - } - - lrps = ingAnnotations(ing.GetAnnotations()).limitRPS() - if lrps != 100 { - t.Errorf("Expected 100 in limit by rps but %v was returend", lrps) - } -} - func TestWithoutAnnotations(t *testing.T) { ing := buildIngress() _, err := ParseAnnotations(ing) diff --git a/controllers/nginx/nginx/rewrite/main.go b/core/pkg/ingress/annotations/rewrite/main.go similarity index 53% rename from controllers/nginx/nginx/rewrite/main.go rename to core/pkg/ingress/annotations/rewrite/main.go index c2f0eb71da..6dfce3d63e 100644 --- a/controllers/nginx/nginx/rewrite/main.go +++ b/core/pkg/ingress/annotations/rewrite/main.go @@ -18,11 +18,11 @@ package rewrite import ( "errors" - "strconv" - "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/ingress/core/pkg/ingress/annotations/parser" + "k8s.io/ingress/core/pkg/ingress/defaults" - "k8s.io/contrib/ingress/controllers/nginx/nginx/config" + "k8s.io/kubernetes/pkg/apis/extensions" ) const ( @@ -38,69 +38,24 @@ type Redirect struct { // AddBaseURL indicates if is required to add a base tag in the head // of the responses from the upstream servers AddBaseURL bool - // Should indicates if the location section should be accessible SSL only + // SSLRedirect indicates if the location section is accessible SSL only SSLRedirect bool } -var ( - // ErrMissingSSLRedirect returned error when the ingress does not contains the - // ssl-redirect annotation - ErrMissingSSLRedirect = errors.New("ssl-redirect annotations is missing") - - // ErrInvalidBool gets returned when the str value is not convertible to a bool - ErrInvalidBool = errors.New("ssl-redirect annotations has invalid value") -) - -type ingAnnotations map[string]string - -func (a ingAnnotations) addBaseURL() bool { - val, ok := a[addBaseURL] - if ok { - if b, err := strconv.ParseBool(val); err == nil { - return b - } - } - return false -} - -func (a ingAnnotations) rewriteTo() string { - val, ok := a[rewriteTo] - if ok { - return val - } - return "" -} - -func (a ingAnnotations) sslRedirect() (bool, error) { - val, ok := a[sslRedirect] - if !ok { - return false, ErrMissingSSLRedirect - } - - sr, err := strconv.ParseBool(val) - if err != nil { - return false, ErrInvalidBool - } - - return sr, nil -} - // ParseAnnotations parses the annotations contained in the ingress // rule used to rewrite the defined paths -func ParseAnnotations(cfg config.Configuration, ing *extensions.Ingress) (*Redirect, error) { +func ParseAnnotations(cfg defaults.Backend, ing *extensions.Ingress) (*Redirect, error) { if ing.GetAnnotations() == nil { return &Redirect{}, errors.New("no annotations present") } - annotations := ingAnnotations(ing.GetAnnotations()) - - sslRe, err := annotations.sslRedirect() + sslRe, err := parser.GetBoolAnnotation(sslRedirect, ing) if err != nil { sslRe = cfg.SSLRedirect } - rt := annotations.rewriteTo() - abu := annotations.addBaseURL() + rt, _ := parser.GetStringAnnotation(rewriteTo, ing) + abu, _ := parser.GetBoolAnnotation(addBaseURL, ing) return &Redirect{ Target: rt, AddBaseURL: abu, diff --git a/controllers/nginx/nginx/rewrite/main_test.go b/core/pkg/ingress/annotations/rewrite/main_test.go similarity index 72% rename from controllers/nginx/nginx/rewrite/main_test.go rename to core/pkg/ingress/annotations/rewrite/main_test.go index 0d38315ffb..c20919fd94 100644 --- a/controllers/nginx/nginx/rewrite/main_test.go +++ b/core/pkg/ingress/annotations/rewrite/main_test.go @@ -23,7 +23,7 @@ import ( "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/util/intstr" - "k8s.io/contrib/ingress/controllers/nginx/nginx/config" + "k8s.io/ingress/core/pkg/ingress/defaults" ) const ( @@ -65,38 +65,9 @@ func buildIngress() *extensions.Ingress { } } -func TestAnnotations(t *testing.T) { - ing := buildIngress() - - r := ingAnnotations(ing.GetAnnotations()).rewriteTo() - if r != "" { - t.Error("Expected no redirect") - } - - f := ingAnnotations(ing.GetAnnotations()).addBaseURL() - if f { - t.Errorf("Expected false in add-base-url but %v was returend", f) - } - - data := map[string]string{} - data[rewriteTo] = defRoute - data[addBaseURL] = "true" - ing.SetAnnotations(data) - - r = ingAnnotations(ing.GetAnnotations()).rewriteTo() - if r != defRoute { - t.Errorf("Expected %v in rewrite but %v was returend", defRoute, r) - } - - f = ingAnnotations(ing.GetAnnotations()).addBaseURL() - if !f { - t.Errorf("Expected true in add-base-url but %v was returend", f) - } -} - func TestWithoutAnnotations(t *testing.T) { ing := buildIngress() - _, err := ParseAnnotations(config.NewDefault(), ing) + _, err := ParseAnnotations(defaults.Backend{}, ing) if err == nil { t.Error("Expected error with ingress without annotations") } @@ -109,7 +80,7 @@ func TestRedirect(t *testing.T) { data[rewriteTo] = defRoute ing.SetAnnotations(data) - redirect, err := ParseAnnotations(config.NewDefault(), ing) + redirect, err := ParseAnnotations(defaults.Backend{}, ing) if err != nil { t.Errorf("Uxpected error with ingress: %v", err) } @@ -122,7 +93,7 @@ func TestRedirect(t *testing.T) { func TestSSLRedirect(t *testing.T) { ing := buildIngress() - cfg := config.Configuration{SSLRedirect: true} + cfg := defaults.Backend{SSLRedirect: true} data := map[string]string{} diff --git a/controllers/nginx/nginx/secureupstream/main.go b/core/pkg/ingress/annotations/secureupstream/main.go similarity index 69% rename from controllers/nginx/nginx/secureupstream/main.go rename to core/pkg/ingress/annotations/secureupstream/main.go index 61e00a9437..f80f36c89b 100644 --- a/controllers/nginx/nginx/secureupstream/main.go +++ b/core/pkg/ingress/annotations/secureupstream/main.go @@ -17,8 +17,7 @@ limitations under the License. package secureupstream import ( - "errors" - "strconv" + "k8s.io/ingress/core/pkg/ingress/annotations/parser" "k8s.io/kubernetes/pkg/apis/extensions" ) @@ -27,24 +26,8 @@ const ( secureUpstream = "ingress.kubernetes.io/secure-backends" ) -type ingAnnotations map[string]string - -func (a ingAnnotations) secureUpstream() bool { - val, ok := a[secureUpstream] - 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 upstream servers should use SSL func ParseAnnotations(ing *extensions.Ingress) (bool, error) { - if ing.GetAnnotations() == nil { - return false, errors.New("no annotations present") - } - - return ingAnnotations(ing.GetAnnotations()).secureUpstream(), nil + return parser.GetBoolAnnotation(secureUpstream, ing) } diff --git a/controllers/nginx/nginx/secureupstream/main_test.go b/core/pkg/ingress/annotations/secureupstream/main_test.go similarity index 92% rename from controllers/nginx/nginx/secureupstream/main_test.go rename to core/pkg/ingress/annotations/secureupstream/main_test.go index d2a2b67e3e..eeb319600c 100644 --- a/controllers/nginx/nginx/secureupstream/main_test.go +++ b/core/pkg/ingress/annotations/secureupstream/main_test.go @@ -65,9 +65,9 @@ func TestAnnotations(t *testing.T) { data[secureUpstream] = "true" ing.SetAnnotations(data) - su := ingAnnotations(ing.GetAnnotations()).secureUpstream() - if !su { - t.Errorf("Expected true in secure-backends but %v was returned", su) + _, err := ParseAnnotations(ing) + if err != nil { + t.Error("Expected error with ingress without annotations") } } diff --git a/core/pkg/ingress/annotations/service/service.go b/core/pkg/ingress/annotations/service/service.go new file mode 100644 index 0000000000..0615645c80 --- /dev/null +++ b/core/pkg/ingress/annotations/service/service.go @@ -0,0 +1,73 @@ +/* +Copyright 2015 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 service + +import ( + "encoding/json" + "fmt" + "strconv" + + "k8s.io/kubernetes/pkg/api" + + "github.com/golang/glog" +) + +const ( + // NamedPortAnnotation annotation used to map named port in services + NamedPortAnnotation = "ingress.kubernetes.io/named-ports" +) + +type namedPortMapping map[string]string + +// getPort returns the port defined in a named port +func (npm namedPortMapping) getPort(name string) (string, bool) { + val, ok := npm.getPortMappings()[name] + return val, ok +} + +// getPortMappings returns a map containing the mapping of named ports names and number +func (npm namedPortMapping) getPortMappings() map[string]string { + data := npm[NamedPortAnnotation] + var mapping map[string]string + if data == "" { + return mapping + } + if err := json.Unmarshal([]byte(data), &mapping); err != nil { + glog.Errorf("unexpected error reading annotations: %v", err) + } + + return mapping +} + +// GetPortMapping returns the number of the named port or an error if is not valid +func GetPortMapping(name string, s *api.Service) (int32, error) { + if s == nil { + return -1, fmt.Errorf("impossible to extract por mapping from %v (missing service)", name) + } + namedPorts := s.ObjectMeta.Annotations + val, ok := namedPortMapping(namedPorts).getPort(name) + if ok { + port, err := strconv.Atoi(val) + if err != nil { + return -1, fmt.Errorf("service %v contains an invalid port mapping for %v (%v), %v", s.Name, name, val, err) + } + + return int32(port), nil + } + + return -1, fmt.Errorf("there is no port with name %v", name) +} diff --git a/core/pkg/ingress/annotations/sslpassthrough/main.go b/core/pkg/ingress/annotations/sslpassthrough/main.go new file mode 100644 index 0000000000..b4d70973f5 --- /dev/null +++ b/core/pkg/ingress/annotations/sslpassthrough/main.go @@ -0,0 +1,45 @@ +/* +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 sslpassthrough + +import ( + "fmt" + + "k8s.io/ingress/core/pkg/ingress/annotations/parser" + "k8s.io/ingress/core/pkg/ingress/defaults" + + "k8s.io/kubernetes/pkg/apis/extensions" +) + +const ( + passthrough = "ingress.kubernetes.io/ssl-passthrough" +) + +// ParseAnnotations parses the annotations contained in the ingress +// rule used to indicate if is required to configure +func ParseAnnotations(cfg defaults.Backend, ing *extensions.Ingress) (bool, error) { + + if ing.GetAnnotations() == nil { + return false, parser.ErrMissingAnnotations + } + + if len(ing.Spec.TLS) == 0 { + return false, fmt.Errorf("ingres rule %v/%v does not contains a TLS section", ing.Name, ing.Namespace) + } + + return parser.GetBoolAnnotation(passthrough, ing) +} diff --git a/core/pkg/ingress/annotations/sslpassthrough/main_test.go b/core/pkg/ingress/annotations/sslpassthrough/main_test.go new file mode 100644 index 0000000000..1ae6d64b36 --- /dev/null +++ b/core/pkg/ingress/annotations/sslpassthrough/main_test.go @@ -0,0 +1,74 @@ +/* +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 sslpassthrough + +import ( + "testing" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/util/intstr" + + "k8s.io/ingress/core/pkg/ingress/defaults" +) + +func buildIngress() *extensions.Ingress { + return &extensions.Ingress{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Namespace: api.NamespaceDefault, + }, + Spec: extensions.IngressSpec{ + Backend: &extensions.IngressBackend{ + ServiceName: "default-backend", + ServicePort: intstr.FromInt(80), + }, + }, + } +} + +func TestParseAnnotations(t *testing.T) { + ing := buildIngress() + + _, err := ParseAnnotations(defaults.Backend{}, ing) + if err == nil { + t.Errorf("unexpected error: %v", err) + } + + data := map[string]string{} + data[passthrough] = "true" + ing.SetAnnotations(data) + // test ingress using the annotation without a TLS section + val, err := ParseAnnotations(defaults.Backend{}, ing) + if err == nil { + t.Errorf("expected error parsing an invalid cidr") + } + + // test with a valid host + ing.Spec.TLS = []extensions.IngressTLS{ + { + Hosts: []string{"foo.bar.com"}, + }, + } + val, err = ParseAnnotations(defaults.Backend{}, ing) + if err != nil { + t.Errorf("expected error parsing an invalid cidr") + } + if !val { + t.Errorf("expected true but false returned") + } +} diff --git a/core/pkg/ingress/controller/backend_ssl.go b/core/pkg/ingress/controller/backend_ssl.go new file mode 100644 index 0000000000..eea0539138 --- /dev/null +++ b/core/pkg/ingress/controller/backend_ssl.go @@ -0,0 +1,161 @@ +/* +Copyright 2015 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 controller + +import ( + "fmt" + "strings" + "time" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/client/cache" + + "github.com/golang/glog" + "k8s.io/ingress/core/pkg/ingress" + "k8s.io/ingress/core/pkg/ingress/annotations/parser" + ssl "k8s.io/ingress/core/pkg/net/ssl" +) + +// syncSecret keeps in sync Secrets used by Ingress rules with files to allow +// being used in controllers. +func (ic *GenericController) syncSecret(k interface{}) error { + if ic.secretQueue.IsShuttingDown() { + return nil + } + if !ic.controllersInSync() { + time.Sleep(podStoreSyncedPollPeriod) + return fmt.Errorf("deferring sync till endpoints controller has synced") + } + + // check if the default certificate is configured + key := fmt.Sprintf("default/%v", defServerName) + _, exists := ic.sslCertTracker.Get(key) + var cert *ingress.SSLCert + var err error + if !exists { + if ic.cfg.DefaultSSLCertificate != "" { + cert, err = ic.getPemCertificate(ic.cfg.DefaultSSLCertificate) + if err != nil { + return err + } + } else { + defCert, defKey := ssl.GetFakeSSLCert() + cert, err = ssl.AddOrUpdateCertAndKey("system-snake-oil-certificate", defCert, defKey, []byte{}) + if err != nil { + return nil + } + } + cert.Name = defServerName + cert.Namespace = api.NamespaceDefault + ic.sslCertTracker.Add(key, cert) + } + + key = k.(string) + + // get secret + secObj, exists, err := ic.secrLister.Store.GetByKey(key) + if err != nil { + return fmt.Errorf("error getting secret %v: %v", key, err) + } + if !exists { + return fmt.Errorf("secret %v was not found", key) + } + sec := secObj.(*api.Secret) + if !ic.secrReferenced(sec.Name, sec.Namespace) { + glog.V(2).Infof("secret %v/%v is not used in Ingress rules. skipping ", sec.Namespace, sec.Name) + return nil + } + + cert, err = ic.getPemCertificate(key) + if err != nil { + return err + } + + // create certificates and add or update the item in the store + _, exists = ic.sslCertTracker.Get(key) + if exists { + ic.sslCertTracker.Update(key, cert) + return nil + } + ic.sslCertTracker.Add(key, cert) + return nil +} + +func (ic *GenericController) getPemCertificate(secretName string) (*ingress.SSLCert, error) { + secretInterface, exists, err := ic.secrLister.Store.GetByKey(secretName) + if err != nil { + return nil, fmt.Errorf("Error retriveing secret %v: %v", secretName, err) + } + if !exists { + return nil, fmt.Errorf("secret named %v does not exists", secretName) + } + + secret := secretInterface.(*api.Secret) + cert, ok := secret.Data[api.TLSCertKey] + if !ok { + return nil, fmt.Errorf("secret named %v has no private key", secretName) + } + key, ok := secret.Data[api.TLSPrivateKeyKey] + if !ok { + return nil, fmt.Errorf("secret named %v has no cert", secretName) + } + + ca := secret.Data["ca.crt"] + + nsSecName := strings.Replace(secretName, "/", "-", -1) + s, err := ssl.AddOrUpdateCertAndKey(nsSecName, cert, key, ca) + if err != nil { + return nil, err + } + + s.Name = secret.Name + s.Namespace = secret.Namespace + return s, nil +} + +// check if secret is referenced in this controller's config +func (ic *GenericController) secrReferenced(name, namespace string) bool { + for _, ingIf := range ic.ingLister.Store.List() { + ing := ingIf.(*extensions.Ingress) + str, err := parser.GetStringAnnotation("ingress.kubernetes.io/auth-tls-secret", ing) + if err == nil && str == fmt.Sprintf("%v/%v", namespace, name) { + return true + } + + if ing.Namespace != namespace { + continue + } + for _, tls := range ing.Spec.TLS { + if tls.SecretName == name { + return true + } + } + } + return false +} + +// sslCertTracker ... +type sslCertTracker struct { + cache.ThreadSafeStore +} + +func newSSLCertTracker() *sslCertTracker { + return &sslCertTracker{ + cache.NewThreadSafeStore(cache.Indexers{}, cache.Indices{}), + } +} diff --git a/core/pkg/ingress/controller/controller.go b/core/pkg/ingress/controller/controller.go new file mode 100644 index 0000000000..be0e782945 --- /dev/null +++ b/core/pkg/ingress/controller/controller.go @@ -0,0 +1,1076 @@ +/* +Copyright 2015 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 controller + +import ( + "fmt" + "net/http" + "reflect" + "sort" + "strconv" + "strings" + "sync" + "time" + + "github.com/golang/glog" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/client/cache" + clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" + unversionedcore "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion" + "k8s.io/kubernetes/pkg/client/record" + "k8s.io/kubernetes/pkg/fields" + "k8s.io/kubernetes/pkg/healthz" + "k8s.io/kubernetes/pkg/util/flowcontrol" + "k8s.io/kubernetes/pkg/util/intstr" + + cache_store "k8s.io/ingress/core/pkg/cache" + "k8s.io/ingress/core/pkg/ingress" + "k8s.io/ingress/core/pkg/ingress/annotations/auth" + "k8s.io/ingress/core/pkg/ingress/annotations/authreq" + "k8s.io/ingress/core/pkg/ingress/annotations/authtls" + "k8s.io/ingress/core/pkg/ingress/annotations/cors" + "k8s.io/ingress/core/pkg/ingress/annotations/healthcheck" + "k8s.io/ingress/core/pkg/ingress/annotations/ipwhitelist" + "k8s.io/ingress/core/pkg/ingress/annotations/proxy" + "k8s.io/ingress/core/pkg/ingress/annotations/ratelimit" + "k8s.io/ingress/core/pkg/ingress/annotations/rewrite" + "k8s.io/ingress/core/pkg/ingress/annotations/secureupstream" + "k8s.io/ingress/core/pkg/ingress/annotations/service" + "k8s.io/ingress/core/pkg/ingress/annotations/sslpassthrough" + "k8s.io/ingress/core/pkg/ingress/status" + "k8s.io/ingress/core/pkg/k8s" + local_strings "k8s.io/ingress/core/pkg/strings" + "k8s.io/ingress/core/pkg/task" +) + +const ( + defUpstreamName = "upstream-default-backend" + defServerName = "_" + podStoreSyncedPollPeriod = 1 * time.Second + rootLocation = "/" + + // ingressClassKey picks a specific "class" for the Ingress. The controller + // only processes Ingresses with this annotation either unset, or set + // to either the configured value or the empty string. + ingressClassKey = "kubernetes.io/ingress.class" +) + +var ( + // list of ports that cannot be used by TCP or UDP services + reservedPorts = []string{"80", "443", "8181", "18080"} +) + +// Interface holds the methods to handle an Ingress backend +type Interface interface { + Start() + Stop() error + + Info() string + + healthz.HealthzChecker +} + +// GenericController watches the kubernetes api and adds/removes services from the loadbalancer +type GenericController struct { + healthz.HealthzChecker + + cfg *Configuration + + ingController *cache.Controller + endpController *cache.Controller + svcController *cache.Controller + secrController *cache.Controller + mapController *cache.Controller + + ingLister cache_store.StoreToIngressLister + svcLister cache.StoreToServiceLister + endpLister cache.StoreToEndpointsLister + secrLister cache_store.StoreToSecretsLister + mapLister cache_store.StoreToConfigmapLister + + recorder record.EventRecorder + + syncQueue *task.Queue + + syncStatus status.Sync + + // controller for SSL certificates + sslCertTracker *sslCertTracker + // TaskQueue in charge of keep the secrets referenced from Ingress + // in sync with the files on disk + secretQueue *task.Queue + + syncRateLimiter flowcontrol.RateLimiter + + // stopLock is used to enforce only a single call to Stop is active. + // Needed because we allow stopping through an http endpoint and + // allowing concurrent stoppers leads to stack traces. + stopLock *sync.Mutex + + stopCh chan struct{} +} + +// Configuration contains all the settings required by an Ingress controller +type Configuration struct { + Client *clientset.Clientset + + ResyncPeriod time.Duration + DefaultService string + IngressClass string + Namespace string + ConfigMapName string + // optional + TCPConfigMapName string + // optional + UDPConfigMapName string + DefaultSSLCertificate string + DefaultHealthzURL string + // optional + PublishService string + + Backend ingress.Controller +} + +// newIngressController creates an Ingress controller +func newIngressController(config *Configuration) Interface { + + eventBroadcaster := record.NewBroadcaster() + eventBroadcaster.StartLogging(glog.Infof) + eventBroadcaster.StartRecordingToSink(unversionedcore.EventSinkImpl{ + Interface: config.Client.Core().Events(config.Namespace), + }) + + ic := GenericController{ + cfg: config, + stopLock: &sync.Mutex{}, + stopCh: make(chan struct{}), + syncRateLimiter: flowcontrol.NewTokenBucketRateLimiter(0.1, 1), + recorder: eventBroadcaster.NewRecorder(api.EventSource{ + Component: "ingress-controller", + }), + sslCertTracker: newSSLCertTracker(), + } + + ic.syncQueue = task.NewTaskQueue(ic.sync) + ic.secretQueue = task.NewTaskQueue(ic.syncSecret) + + // from here to the end of the method all the code is just boilerplate + // required to watch Ingress, Secrets, ConfigMaps and Endoints. + // This is used to detect new content, updates or removals and act accordingly + ingEventHandler := cache.ResourceEventHandlerFuncs{ + AddFunc: func(obj interface{}) { + addIng := obj.(*extensions.Ingress) + if !IsValidClass(addIng, config.IngressClass) { + glog.Infof("ignoring add for ingress %v based on annotation %v", addIng.Name, ingressClassKey) + return + } + ic.recorder.Eventf(addIng, api.EventTypeNormal, "CREATE", fmt.Sprintf("Ingress %s/%s", addIng.Namespace, addIng.Name)) + ic.syncQueue.Enqueue(obj) + }, + DeleteFunc: func(obj interface{}) { + delIng := obj.(*extensions.Ingress) + if !IsValidClass(delIng, config.IngressClass) { + glog.Infof("ignoring add for ingress %v based on annotation %v", delIng.Name, ingressClassKey) + return + } + ic.recorder.Eventf(delIng, api.EventTypeNormal, "DELETE", fmt.Sprintf("Ingress %s/%s", delIng.Namespace, delIng.Name)) + ic.syncQueue.Enqueue(obj) + }, + UpdateFunc: func(old, cur interface{}) { + curIng := cur.(*extensions.Ingress) + if !IsValidClass(curIng, config.IngressClass) { + return + } + + if !reflect.DeepEqual(old, cur) { + upIng := cur.(*extensions.Ingress) + ic.recorder.Eventf(upIng, api.EventTypeNormal, "UPDATE", fmt.Sprintf("Ingress %s/%s", upIng.Namespace, upIng.Name)) + ic.syncQueue.Enqueue(cur) + } + }, + } + + secrEventHandler := cache.ResourceEventHandlerFuncs{ + AddFunc: func(obj interface{}) { + sec := obj.(*api.Secret) + ic.secretQueue.Enqueue(sec) + }, + DeleteFunc: func(obj interface{}) { + sec := obj.(*api.Secret) + ic.sslCertTracker.Delete(fmt.Sprintf("%v/%v", sec.Namespace, sec.Name)) + }, + UpdateFunc: func(old, cur interface{}) { + if !reflect.DeepEqual(old, cur) { + sec := cur.(*api.Secret) + ic.secretQueue.Enqueue(sec) + } + }, + } + + eventHandler := cache.ResourceEventHandlerFuncs{ + AddFunc: func(obj interface{}) { + ic.syncQueue.Enqueue(obj) + }, + DeleteFunc: func(obj interface{}) { + ic.syncQueue.Enqueue(obj) + }, + UpdateFunc: func(old, cur interface{}) { + if !reflect.DeepEqual(old, cur) { + ic.syncQueue.Enqueue(cur) + } + }, + } + + mapEventHandler := cache.ResourceEventHandlerFuncs{ + UpdateFunc: func(old, cur interface{}) { + if !reflect.DeepEqual(old, cur) { + upCmap := cur.(*api.ConfigMap) + mapKey := fmt.Sprintf("%s/%s", upCmap.Namespace, upCmap.Name) + // updates to configuration configmaps can trigger an update + if mapKey == ic.cfg.ConfigMapName || mapKey == ic.cfg.TCPConfigMapName || mapKey == ic.cfg.UDPConfigMapName { + ic.recorder.Eventf(upCmap, api.EventTypeNormal, "UPDATE", fmt.Sprintf("ConfigMap %v", mapKey)) + ic.syncQueue.Enqueue(cur) + } + } + }, + } + + ic.ingLister.Store, ic.ingController = cache.NewInformer( + cache.NewListWatchFromClient(ic.cfg.Client.Extensions().RESTClient(), "ingresses", ic.cfg.Namespace, fields.Everything()), + &extensions.Ingress{}, ic.cfg.ResyncPeriod, ingEventHandler) + + ic.endpLister.Store, ic.endpController = cache.NewInformer( + cache.NewListWatchFromClient(ic.cfg.Client.Core().RESTClient(), "endpoints", ic.cfg.Namespace, fields.Everything()), + &api.Endpoints{}, ic.cfg.ResyncPeriod, eventHandler) + + ic.secrLister.Store, ic.secrController = cache.NewInformer( + cache.NewListWatchFromClient(ic.cfg.Client.Core().RESTClient(), "secrets", ic.cfg.Namespace, fields.Everything()), + &api.Secret{}, ic.cfg.ResyncPeriod, secrEventHandler) + + ic.mapLister.Store, ic.mapController = cache.NewInformer( + cache.NewListWatchFromClient(ic.cfg.Client.Core().RESTClient(), "configmaps", ic.cfg.Namespace, fields.Everything()), + &api.ConfigMap{}, ic.cfg.ResyncPeriod, mapEventHandler) + + ic.svcLister.Indexer, ic.svcController = cache.NewIndexerInformer( + cache.NewListWatchFromClient(ic.cfg.Client.Core().RESTClient(), "services", ic.cfg.Namespace, fields.Everything()), + &api.Service{}, + ic.cfg.ResyncPeriod, + cache.ResourceEventHandlerFuncs{}, + cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}) + + ic.syncStatus = status.NewStatusSyncer(status.Config{ + Client: config.Client, + PublishService: ic.cfg.PublishService, + IngressLister: ic.ingLister, + }) + + return ic +} + +func (ic *GenericController) controllersInSync() bool { + return ic.ingController.HasSynced() && + ic.svcController.HasSynced() && + ic.endpController.HasSynced() && + ic.secrController.HasSynced() && + ic.mapController.HasSynced() +} + +// Name returns the healthcheck name +func (ic GenericController) Name() string { + return "Ingress Controller" +} + +// Check returns if the nginx healthz endpoint is returning ok (status code 200) +func (ic GenericController) Check(_ *http.Request) error { + res, err := http.Get("http://127.0.0.1:18080/healthz") + if err != nil { + return err + } + defer res.Body.Close() + if res.StatusCode != 200 { + return fmt.Errorf("Ingress controller is not healthy") + } + return nil +} + +// Info returns information about the backend +func (ic GenericController) Info() string { + return ic.cfg.Backend.Info() +} + +// IngressClass returns information about the backend +func (ic GenericController) IngressClass() string { + return ic.cfg.IngressClass +} + +// getSecret searchs for a secret in the local secrets Store +func (ic *GenericController) getSecret(name string) (*api.Secret, error) { + s, exists, err := ic.secrLister.Store.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, fmt.Errorf("secret %v was not found", name) + } + return s.(*api.Secret), nil +} + +func (ic *GenericController) getConfigMap(ns, name string) (*api.ConfigMap, error) { + // TODO: check why ic.mapLister.Store.GetByKey(mapKey) is not stable (random content) + return ic.cfg.Client.ConfigMaps(ns).Get(name) +} + +// sync collects all the pieces required to assemble the configuration file and +// then sends the content to the backend (OnUpdate) receiving the populated +// template as response reloading the backend if is required. +func (ic *GenericController) sync(key interface{}) error { + ic.syncRateLimiter.Accept() + + if ic.syncQueue.IsShuttingDown() { + return nil + } + + if !ic.controllersInSync() { + time.Sleep(podStoreSyncedPollPeriod) + return fmt.Errorf("deferring sync till endpoints controller has synced") + } + + // by default no custom configuration + cfg := &api.ConfigMap{} + + if ic.cfg.ConfigMapName != "" { + // search for custom configmap (defined in main args) + var err error + ns, name, _ := k8s.ParseNameNS(ic.cfg.ConfigMapName) + cfg, err = ic.getConfigMap(ns, name) + if err != nil { + // requeue + return fmt.Errorf("unexpected error searching configmap %v: %v", ic.cfg.ConfigMapName, err) + } + } + + upstreams, servers := ic.getUpstreamServers() + var passUpstreams []*ingress.SSLPassthroughUpstreams + for _, server := range servers { + if !server.SSLPassthrough { + continue + } + + for _, loc := range server.Locations { + if loc.Path != rootLocation { + continue + } + passUpstreams = append(passUpstreams, &ingress.SSLPassthroughUpstreams{ + Upstream: loc.Upstream, + Host: server.Name, + }) + break + } + } + + data, err := ic.cfg.Backend.OnUpdate(cfg, ingress.Configuration{ + HealthzURL: ic.cfg.DefaultHealthzURL, + Upstreams: upstreams, + Servers: servers, + TCPUpstreams: ic.getTCPServices(), + UDPUpstreams: ic.getUDPServices(), + PassthroughUpstreams: passUpstreams, + }) + if err != nil { + return err + } + + if !ic.cfg.Backend.IsReloadRequired(data) { + return nil + } + + glog.Infof("reloading ingress backend...") + out, err := ic.cfg.Backend.Restart(data) + if err != nil { + incReloadErrorCount() + glog.Errorf("unexpected failure restarting the backend: \n%v", string(out)) + return err + } + glog.Infof("ingress backend successfully reloaded...") + incReloadCount() + return nil +} + +func (ic *GenericController) getTCPServices() []*ingress.Location { + if ic.cfg.TCPConfigMapName == "" { + // no configmap for TCP services + return []*ingress.Location{} + } + + ns, name, err := k8s.ParseNameNS(ic.cfg.TCPConfigMapName) + if err != nil { + glog.Warningf("%v", err) + return []*ingress.Location{} + } + tcpMap, err := ic.getConfigMap(ns, name) + if err != nil { + glog.V(5).Infof("no configured tcp services found: %v", err) + return []*ingress.Location{} + } + + return ic.getStreamServices(tcpMap.Data, api.ProtocolTCP) +} + +func (ic *GenericController) getUDPServices() []*ingress.Location { + if ic.cfg.UDPConfigMapName == "" { + // no configmap for TCP services + return []*ingress.Location{} + } + + ns, name, err := k8s.ParseNameNS(ic.cfg.UDPConfigMapName) + if err != nil { + glog.Warningf("%v", err) + return []*ingress.Location{} + } + tcpMap, err := ic.getConfigMap(ns, name) + if err != nil { + glog.V(3).Infof("no configured tcp services found: %v", err) + return []*ingress.Location{} + } + + return ic.getStreamServices(tcpMap.Data, api.ProtocolUDP) +} + +func (ic *GenericController) getStreamServices(data map[string]string, proto api.Protocol) []*ingress.Location { + var svcs []*ingress.Location + // k -> port to expose + // v -> /: + for k, v := range data { + port, err := strconv.Atoi(k) + if err != nil { + glog.Warningf("%v is not valid as a TCP port", k) + continue + } + + // this ports used by the backend + if local_strings.StringInSlice(k, reservedPorts) { + glog.Warningf("port %v cannot be used for TCP or UDP services. It is reserved for the Ingress controller", k) + continue + } + + nsSvcPort := strings.Split(v, ":") + if len(nsSvcPort) != 2 { + glog.Warningf("invalid format (namespace/name:port) '%v'", k) + continue + } + + nsName := nsSvcPort[0] + svcPort := nsSvcPort[1] + + svcNs, svcName, err := k8s.ParseNameNS(nsName) + if err != nil { + glog.Warningf("%v", err) + continue + } + + svcObj, svcExists, err := ic.svcLister.Indexer.GetByKey(nsName) + if err != nil { + glog.Warningf("error getting service %v: %v", nsName, err) + continue + } + + if !svcExists { + glog.Warningf("service %v was not found", nsName) + continue + } + + svc := svcObj.(*api.Service) + + var endps []ingress.UpstreamServer + targetPort, err := strconv.Atoi(svcPort) + if err != nil { + for _, sp := range svc.Spec.Ports { + if sp.Name == svcPort { + endps = ic.getEndpoints(svc, sp.TargetPort, proto, &healthcheck.Upstream{}) + break + } + } + } else { + // we need to use the TargetPort (where the endpoints are running) + for _, sp := range svc.Spec.Ports { + if sp.Port == int32(targetPort) { + endps = ic.getEndpoints(svc, sp.TargetPort, proto, &healthcheck.Upstream{}) + break + } + } + } + + sort.Sort(ingress.UpstreamServerByAddrPort(endps)) + + // tcp upstreams cannot contain empty upstreams and there is no + // default backend equivalent for TCP + if len(endps) == 0 { + glog.Warningf("service %v/%v does not have any active endpoints", svcNs, svcName) + continue + } + + svcs = append(svcs, &ingress.Location{ + Path: k, + Upstream: ingress.Upstream{ + Name: fmt.Sprintf("%v-%v-%v", svcNs, svcName, port), + Backends: endps, + }, + }) + } + + return svcs +} + +// getDefaultUpstream returns an upstream associated with the +// default backend service. In case of error retrieving information +// configure the upstream to return http code 503. +func (ic *GenericController) getDefaultUpstream() *ingress.Upstream { + upstream := &ingress.Upstream{ + Name: defUpstreamName, + } + svcKey := ic.cfg.DefaultService + svcObj, svcExists, err := ic.svcLister.Indexer.GetByKey(svcKey) + if err != nil { + glog.Warningf("unexpected error searching the default backend %v: %v", ic.cfg.DefaultService, err) + upstream.Backends = append(upstream.Backends, newDefaultServer()) + return upstream + } + + if !svcExists { + glog.Warningf("service %v does not exists", svcKey) + upstream.Backends = append(upstream.Backends, newDefaultServer()) + return upstream + } + + svc := svcObj.(*api.Service) + endps := ic.getEndpoints(svc, svc.Spec.Ports[0].TargetPort, api.ProtocolTCP, &healthcheck.Upstream{}) + if len(endps) == 0 { + glog.Warningf("service %v does not have any active endpoints", svcKey) + endps = []ingress.UpstreamServer{newDefaultServer()} + } + + upstream.Backends = append(upstream.Backends, endps...) + return upstream +} + +type ingressByRevision []interface{} + +func (c ingressByRevision) Len() int { return len(c) } +func (c ingressByRevision) Swap(i, j int) { c[i], c[j] = c[j], c[i] } +func (c ingressByRevision) Less(i, j int) bool { + ir := c[i].(*extensions.Ingress).ResourceVersion + jr := c[j].(*extensions.Ingress).ResourceVersion + return ir < jr +} + +// getUpstreamServers returns a list of Upstream and Server to be used by the backend +// An upstream can be used in multiple servers if the namespace, service name and port are the same +func (ic *GenericController) getUpstreamServers() ([]*ingress.Upstream, []*ingress.Server) { + ings := ic.ingLister.Store.List() + sort.Sort(ingressByRevision(ings)) + + upstreams := ic.createUpstreams(ings) + servers := ic.createServers(ings, upstreams) + + upsDefaults := ic.cfg.Backend.UpstreamDefaults() + + for _, ingIf := range ings { + ing := ingIf.(*extensions.Ingress) + + nginxAuth, err := auth.ParseAnnotations(ing, auth.DefAuthDirectory, ic.getSecret) + glog.V(5).Infof("auth annotation: %v", nginxAuth) + if err != nil { + glog.V(5).Infof("error reading authentication in Ingress %v/%v: %v", ing.GetNamespace(), ing.GetName(), err) + } + + rl, err := ratelimit.ParseAnnotations(ing) + glog.V(5).Infof("rate limit annotation: %v", rl) + if err != nil { + glog.V(5).Infof("error reading rate limit annotation in Ingress %v/%v: %v", ing.GetNamespace(), ing.GetName(), err) + } + + secUpstream, err := secureupstream.ParseAnnotations(ing) + if err != nil { + glog.V(5).Infof("error reading secure upstream in Ingress %v/%v: %v", ing.GetNamespace(), ing.GetName(), err) + } + + locRew, err := rewrite.ParseAnnotations(upsDefaults, ing) + if err != nil { + glog.V(5).Infof("error parsing rewrite annotations for Ingress rule %v/%v: %v", ing.GetNamespace(), ing.GetName(), err) + } + + wl, err := ipwhitelist.ParseAnnotations(upsDefaults, ing) + glog.V(5).Infof("white list annotation: %v", wl) + if err != nil { + glog.V(5).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(5).Infof("error reading CORS annotation in Ingress %v/%v: %v", ing.GetNamespace(), ing.GetName(), err) + } + + ra, err := authreq.ParseAnnotations(ing) + glog.V(5).Infof("auth request annotation: %v", ra) + if err != nil { + glog.V(5).Infof("error reading auth request annotation in Ingress %v/%v: %v", ing.GetNamespace(), ing.GetName(), err) + } + + prx := proxy.ParseAnnotations(upsDefaults, ing) + glog.V(5).Infof("proxy timeouts annotation: %v", prx) + + certAuth, err := authtls.ParseAnnotations(ing, ic.getAuthCertificate) + glog.V(5).Infof("auth request annotation: %v", certAuth) + if err != nil { + glog.V(5).Infof("error reading certificate auth annotation in Ingress %v/%v: %v", ing.GetNamespace(), ing.GetName(), err) + } + + for _, rule := range ing.Spec.Rules { + host := rule.Host + if host == "" { + host = defServerName + } + server := servers[host] + if server == nil { + server = servers[defServerName] + } + + // use default upstream + defBackend := upstreams[defUpstreamName] + // we need to check if the spec contains the default backend + if ing.Spec.Backend != nil { + glog.V(3).Infof("ingress rule %v/%v defines a default Backend %v/%v", + ing.Namespace, + ing.Name, + ing.Spec.Backend.ServiceName, + ing.Spec.Backend.ServicePort.String()) + + name := fmt.Sprintf("%v-%v-%v", + ing.GetNamespace(), + ing.Spec.Backend.ServiceName, + ing.Spec.Backend.ServicePort.String()) + + if defUps, ok := upstreams[name]; ok { + defBackend = defUps + } + } + + if rule.HTTP == nil && + len(ing.Spec.TLS) == 0 && + host != defServerName { + glog.V(3).Infof("ingress rule %v/%v does not contains HTTP or TLS rules. using default backend", ing.Namespace, ing.Name) + server.Locations[0].Upstream = *defBackend + continue + } + + for _, path := range rule.HTTP.Paths { + upsName := fmt.Sprintf("%v-%v-%v", + ing.GetNamespace(), + path.Backend.ServiceName, + path.Backend.ServicePort.String()) + + ups := upstreams[upsName] + + // if there's no path defined we assume / + nginxPath := rootLocation + if path.Path != "" { + nginxPath = path.Path + } + + addLoc := true + for _, loc := range server.Locations { + if loc.Path == nginxPath { + addLoc = false + + if !loc.IsDefBackend { + glog.V(3).Infof("avoiding replacement of ingress rule %v/%v location %v upstream %v (%v)", ing.Namespace, ing.Name, loc.Path, ups.Name, loc.Upstream.Name) + break + } + + glog.V(3).Infof("replacing ingress rule %v/%v location %v upstream %v (%v)", ing.Namespace, ing.Name, loc.Path, ups.Name, loc.Upstream.Name) + loc.Upstream = *ups + loc.IsDefBackend = false + loc.BasicDigestAuth = *nginxAuth + loc.RateLimit = *rl + loc.Redirect = *locRew + loc.SecureUpstream = secUpstream + loc.Whitelist = *wl + loc.Upstream = *ups + loc.EnableCORS = eCORS + loc.ExternalAuth = ra + loc.Proxy = *prx + loc.CertificateAuth = *certAuth + break + } + } + // is a new location + if addLoc { + glog.V(3).Infof("adding location %v in ingress rule %v/%v upstream", nginxPath, ing.Namespace, ing.Name, ups.Name) + server.Locations = append(server.Locations, &ingress.Location{ + Path: nginxPath, + Upstream: *ups, + IsDefBackend: false, + BasicDigestAuth: *nginxAuth, + RateLimit: *rl, + Redirect: *locRew, + SecureUpstream: secUpstream, + Whitelist: *wl, + EnableCORS: eCORS, + ExternalAuth: ra, + Proxy: *prx, + CertificateAuth: *certAuth, + }) + } + } + } + } + + // TODO: find a way to make this more readable + // The structs must be ordered to always generate the same file + // if the content does not change. + aUpstreams := make([]*ingress.Upstream, 0, len(upstreams)) + for _, value := range upstreams { + if len(value.Backends) == 0 { + glog.V(3).Infof("upstream %v does not have any active endpoints. Using default backend", value.Name) + value.Backends = append(value.Backends, newDefaultServer()) + } + sort.Sort(ingress.UpstreamServerByAddrPort(value.Backends)) + aUpstreams = append(aUpstreams, value) + } + sort.Sort(ingress.UpstreamByNameServers(aUpstreams)) + + aServers := make([]*ingress.Server, 0, len(servers)) + for _, value := range servers { + sort.Sort(ingress.LocationByPath(value.Locations)) + aServers = append(aServers, value) + } + sort.Sort(ingress.ServerByName(aServers)) + + return aUpstreams, aServers +} + +func (ic *GenericController) getAuthCertificate(secretName string) (*authtls.SSLCert, error) { + bc, exists := ic.sslCertTracker.Get(secretName) + if !exists { + return &authtls.SSLCert{}, fmt.Errorf("secret %v does not exists", secretName) + } + cert := bc.(*ingress.SSLCert) + return &authtls.SSLCert{ + Secret: secretName, + CertFileName: cert.PemFileName, + CAFileName: cert.CAFileName, + PemSHA: cert.PemSHA, + }, nil +} + +// createUpstreams creates the NGINX upstreams for each service referenced in +// Ingress rules. The servers inside the upstream are endpoints. +func (ic *GenericController) createUpstreams(data []interface{}) map[string]*ingress.Upstream { + upstreams := make(map[string]*ingress.Upstream) + upstreams[defUpstreamName] = ic.getDefaultUpstream() + + upsDefaults := ic.cfg.Backend.UpstreamDefaults() + for _, ingIf := range data { + ing := ingIf.(*extensions.Ingress) + + hz := healthcheck.ParseAnnotations(upsDefaults, ing) + + var defBackend string + if ing.Spec.Backend != nil { + defBackend = fmt.Sprintf("%v-%v-%v", + ing.GetNamespace(), + ing.Spec.Backend.ServiceName, + ing.Spec.Backend.ServicePort.String()) + + glog.V(3).Infof("creating upstream %v", defBackend) + upstreams[defBackend] = newUpstream(defBackend) + + svcKey := fmt.Sprintf("%v/%v", ing.GetNamespace(), ing.Spec.Backend.ServiceName) + endps, err := ic.serviceEndpoints(svcKey, ing.Spec.Backend.ServicePort.String(), hz) + upstreams[defBackend].Backends = append(upstreams[defBackend].Backends, endps...) + if err != nil { + glog.Warningf("error creating upstream %v: %v", defBackend, err) + } + } + + for _, rule := range ing.Spec.Rules { + if rule.HTTP == nil { + continue + } + + for _, path := range rule.HTTP.Paths { + name := fmt.Sprintf("%v-%v-%v", + ing.GetNamespace(), + path.Backend.ServiceName, + path.Backend.ServicePort.String()) + + if _, ok := upstreams[name]; ok { + continue + } + + glog.V(3).Infof("creating upstream %v", name) + upstreams[name] = newUpstream(name) + + svcKey := fmt.Sprintf("%v/%v", ing.GetNamespace(), path.Backend.ServiceName) + endp, err := ic.serviceEndpoints(svcKey, path.Backend.ServicePort.String(), hz) + if err != nil { + glog.Warningf("error obtaining service endpoints: %v", err) + continue + } + upstreams[name].Backends = endp + } + } + } + + return upstreams +} + +// serviceEndpoints returns the upstream servers (endpoints) associated +// to a service. +func (ic *GenericController) serviceEndpoints(svcKey, backendPort string, + hz *healthcheck.Upstream) ([]ingress.UpstreamServer, error) { + svcObj, svcExists, err := ic.svcLister.Indexer.GetByKey(svcKey) + + var upstreams []ingress.UpstreamServer + if err != nil { + return upstreams, fmt.Errorf("error getting service %v from the cache: %v", svcKey, err) + } + + if !svcExists { + err = fmt.Errorf("service %v does not exists", svcKey) + return upstreams, err + } + + svc := svcObj.(*api.Service) + glog.V(3).Infof("obtaining port information for service %v", svcKey) + for _, servicePort := range svc.Spec.Ports { + // targetPort could be a string, use the name or the port (int) + if strconv.Itoa(int(servicePort.Port)) == backendPort || + servicePort.TargetPort.String() == backendPort || + servicePort.Name == backendPort { + + endps := ic.getEndpoints(svc, servicePort.TargetPort, api.ProtocolTCP, hz) + if len(endps) == 0 { + glog.Warningf("service %v does not have any active endpoints", svcKey) + } + + upstreams = append(upstreams, endps...) + break + } + } + + return upstreams, nil +} + +func (ic *GenericController) createServers(data []interface{}, upstreams map[string]*ingress.Upstream) map[string]*ingress.Server { + servers := make(map[string]*ingress.Server) + ngxProxy := *proxy.ParseAnnotations(ic.cfg.Backend.UpstreamDefaults(), nil) + + upsDefaults := ic.cfg.Backend.UpstreamDefaults() + + // default server + servers[defServerName] = &ingress.Server{ + Name: defServerName, + Locations: []*ingress.Location{ + { + Path: rootLocation, + IsDefBackend: true, + Upstream: *ic.getDefaultUpstream(), + Proxy: ngxProxy, + }, + }} + + // initialize all the servers + for _, ingIf := range data { + ing := ingIf.(*extensions.Ingress) + // check if ssl passthrough is configured + sslpt, err := sslpassthrough.ParseAnnotations(upsDefaults, ing) + if err != nil { + glog.V(5).Infof("error reading ssl passthrough annotation in Ingress %v/%v: %v", ing.GetNamespace(), ing.GetName(), err) + } + + for _, rule := range ing.Spec.Rules { + host := rule.Host + if host == "" { + host = defServerName + } + if _, ok := servers[host]; ok { + // server already configured + continue + } + servers[host] = &ingress.Server{ + Name: host, + Locations: []*ingress.Location{ + { + Path: rootLocation, + IsDefBackend: true, + Upstream: *ic.getDefaultUpstream(), + Proxy: ngxProxy, + }, + }, SSLPassthrough: sslpt} + } + } + + // configure default location and SSL + for _, ingIf := range data { + ing := ingIf.(*extensions.Ingress) + + for _, rule := range ing.Spec.Rules { + host := rule.Host + if host == "" { + host = defServerName + } + + // only add certificate if the server does not have one previously configured + if len(ing.Spec.TLS) > 0 && !servers[host].SSL { + key := fmt.Sprintf("%v/%v", ing.Namespace, ing.Spec.TLS[0].SecretName) + bc, exists := ic.sslCertTracker.Get(key) + if exists { + cert := bc.(*ingress.SSLCert) + if isHostValid(host, cert) { + servers[host].SSL = true + servers[host].SSLCertificate = cert.PemFileName + //servers[host].SSLCertificateKey = cert.PemFileName + servers[host].SSLPemChecksum = cert.PemSHA + } + } + } + + if ing.Spec.Backend != nil { + defUpstream := fmt.Sprintf("%v-%v-%v", ing.GetNamespace(), ing.Spec.Backend.ServiceName, ing.Spec.Backend.ServicePort.String()) + if backendUpstream, ok := upstreams[defUpstream]; ok { + if host == "" || host == defServerName { + ic.recorder.Eventf(ing, api.EventTypeWarning, "MAPPING", "error: rules with Spec.Backend are allowed only with hostnames") + continue + } + servers[host].Locations[0].Upstream = *backendUpstream + } + } + } + } + + return servers +} + +// getEndpoints returns a list of : for a given service/target port combination. +func (ic *GenericController) getEndpoints( + s *api.Service, + servicePort intstr.IntOrString, + proto api.Protocol, + hz *healthcheck.Upstream) []ingress.UpstreamServer { + glog.V(3).Infof("getting endpoints for service %v/%v and port %v", s.Namespace, s.Name, servicePort.String()) + ep, err := ic.endpLister.GetServiceEndpoints(s) + if err != nil { + glog.Warningf("unexpected error obtaining service endpoints: %v", err) + return []ingress.UpstreamServer{} + } + + upsServers := []ingress.UpstreamServer{} + + for _, ss := range ep.Subsets { + for _, epPort := range ss.Ports { + + if !reflect.DeepEqual(epPort.Protocol, proto) { + continue + } + + var targetPort int32 + + switch servicePort.Type { + case intstr.Int: + if int(epPort.Port) == servicePort.IntValue() { + targetPort = epPort.Port + } + case intstr.String: + port, err := service.GetPortMapping(servicePort.StrVal, s) + if err == nil { + targetPort = port + continue + } + + glog.Warningf("error mapping service port: %v", err) + err = ic.checkSvcForUpdate(s) + if err != nil { + glog.Warningf("error mapping service ports: %v", err) + continue + } + + port, err = service.GetPortMapping(servicePort.StrVal, s) + if err == nil { + targetPort = port + } + } + + // check for invalid port value + if targetPort == -1 { + continue + } + + for _, epAddress := range ss.Addresses { + ups := ingress.UpstreamServer{ + Address: epAddress.IP, + Port: fmt.Sprintf("%v", targetPort), + MaxFails: hz.MaxFails, + FailTimeout: hz.FailTimeout, + } + upsServers = append(upsServers, ups) + } + } + } + + glog.V(3).Infof("endpoints found: %v", upsServers) + return upsServers +} + +// Stop stops the loadbalancer controller. +func (ic GenericController) Stop() error { + ic.stopLock.Lock() + defer ic.stopLock.Unlock() + + // Only try draining the workqueue if we haven't already. + if !ic.syncQueue.IsShuttingDown() { + glog.Infof("shutting down controller queues") + close(ic.stopCh) + go ic.syncQueue.Shutdown() + go ic.secretQueue.Shutdown() + ic.syncStatus.Shutdown() + return nil + } + + return fmt.Errorf("shutdown already in progress") +} + +// Start starts the Ingress controller. +func (ic GenericController) Start() { + glog.Infof("starting Ingress controller") + go ic.cfg.Backend.Start() + + go ic.ingController.Run(ic.stopCh) + go ic.endpController.Run(ic.stopCh) + go ic.svcController.Run(ic.stopCh) + go ic.secrController.Run(ic.stopCh) + go ic.mapController.Run(ic.stopCh) + + go ic.secretQueue.Run(time.Second, ic.stopCh) + go ic.syncQueue.Run(time.Second, ic.stopCh) + + go ic.syncStatus.Run(ic.stopCh) + + <-ic.stopCh +} diff --git a/core/pkg/ingress/controller/launch.go b/core/pkg/ingress/controller/launch.go new file mode 100644 index 0000000000..420c664c82 --- /dev/null +++ b/core/pkg/ingress/controller/launch.go @@ -0,0 +1,182 @@ +package controller + +import ( + "flag" + "fmt" + "net/http" + "net/http/pprof" + "os" + "syscall" + "time" + + "github.com/golang/glog" + "github.com/spf13/pflag" + + "k8s.io/ingress/core/pkg/ingress" + "k8s.io/ingress/core/pkg/k8s" + + "github.com/prometheus/client_golang/prometheus" + "k8s.io/kubernetes/pkg/api" + clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" + "k8s.io/kubernetes/pkg/client/restclient" + "k8s.io/kubernetes/pkg/healthz" + kubectl_util "k8s.io/kubernetes/pkg/kubectl/cmd/util" +) + +// NewIngressController returns a configured Ingress controller ready to start +func NewIngressController(backend ingress.Controller) Interface { + var ( + flags = pflag.NewFlagSet("", pflag.ExitOnError) + + defaultSvc = flags.String("default-backend-service", "", + `Service used to serve a 404 page for the default backend. Takes the form + namespace/name. The controller uses the first node port of this Service for + the default backend.`) + + ingressClass = flags.String("ingress-class", "nginx", + `Name of the ingress class to route through this controller.`) + + configMap = flags.String("configmap", "", + `Name of the ConfigMap that contains the custom configuration to use`) + + publishSvc = flags.String("publish-service", "", + `Service fronting the ingress controllers. Takes the form + namespace/name. The controller will set the endpoint records on the + ingress objects to reflect those on the service.`) + + tcpConfigMapName = flags.String("tcp-services-configmap", "", + `Name of the ConfigMap that contains the definition of the TCP services to expose. + The key in the map indicates the external port to be used. The value is the name of the + service with the format namespace/serviceName and the port of the service could be a + number of the name of the port. + The ports 80 and 443 are not allowed as external ports. This ports are reserved for nginx`) + + udpConfigMapName = flags.String("udp-services-configmap", "", + `Name of the ConfigMap that contains the definition of the UDP services to expose. + The key in the map indicates the external port to be used. The value is the name of the + service with the format namespace/serviceName and the port of the service could be a + number of the name of the port.`) + + resyncPeriod = flags.Duration("sync-period", 60*time.Second, + `Relist and confirm cloud resources this often.`) + + watchNamespace = flags.String("watch-namespace", api.NamespaceAll, + `Namespace to watch for Ingress. Default is to watch all namespaces`) + + healthzPort = flags.Int("healthz-port", 10254, "port for healthz endpoint.") + + profiling = flags.Bool("profiling", true, `Enable profiling via web interface host:port/debug/pprof/`) + + defSSLCertificate = flags.String("default-ssl-certificate", "", `Name of the secret + that contains a SSL certificate to be used as default for a HTTPS catch-all server`) + + defHealthzURL = flags.String("health-check-path", "/healthz", `Defines + the URL to be used as health check inside in the default server in NGINX.`) + ) + + flags.AddGoFlagSet(flag.CommandLine) + flags.Parse(os.Args) + clientConfig := kubectl_util.DefaultClientConfig(flags) + + flag.Set("logtostderr", "true") + + glog.Info(backend.Info()) + + if *ingressClass != "" { + glog.Infof("Watching for ingress class: %s", *ingressClass) + } + + if *defaultSvc == "" { + glog.Fatalf("Please specify --default-backend-service") + } + + kubeconfig, err := restclient.InClusterConfig() + if err != nil { + kubeconfig, err = clientConfig.ClientConfig() + if err != nil { + glog.Fatalf("error configuring the client: %v", err) + } + } + + kubeClient, err := clientset.NewForConfig(kubeconfig) + if err != nil { + glog.Fatalf("failed to create client: %v", err) + } + + _, err = k8s.IsValidService(kubeClient, *defaultSvc) + if err != nil { + glog.Fatalf("no service with name %v found: %v", *defaultSvc, err) + } + glog.Infof("validated %v as the default backend", *defaultSvc) + + if *publishSvc != "" { + svc, err := k8s.IsValidService(kubeClient, *publishSvc) + if err != nil { + glog.Fatalf("no service with name %v found: %v", *publishSvc, err) + } + + if len(svc.Status.LoadBalancer.Ingress) == 0 { + // We could poll here, but we instead just exit and rely on k8s to restart us + glog.Fatalf("service %s does not (yet) have ingress points", *publishSvc) + } + + glog.Infof("service %v validated as source of Ingress status", *publishSvc) + } + + if *configMap != "" { + _, _, err = k8s.ParseNameNS(*configMap) + if err != nil { + glog.Fatalf("configmap error: %v", err) + } + } + + os.MkdirAll(ingress.DefaultSSLDirectory, 0655) + + config := &Configuration{ + Client: kubeClient, + ResyncPeriod: *resyncPeriod, + DefaultService: *defaultSvc, + IngressClass: *ingressClass, + Namespace: *watchNamespace, + ConfigMapName: *configMap, + TCPConfigMapName: *tcpConfigMapName, + UDPConfigMapName: *udpConfigMapName, + DefaultSSLCertificate: *defSSLCertificate, + DefaultHealthzURL: *defHealthzURL, + PublishService: *publishSvc, + Backend: backend, + } + + ic := newIngressController(config) + go registerHandlers(*profiling, *healthzPort, ic) + return ic +} + +func registerHandlers(enableProfiling bool, port int, ic Interface) { + mux := http.NewServeMux() + healthz.InstallHandler(mux, ic) + + mux.Handle("/metrics", prometheus.Handler()) + + mux.HandleFunc("/build", func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + fmt.Fprintf(w, ic.Info()) + }) + + mux.HandleFunc("/stop", func(w http.ResponseWriter, r *http.Request) { + syscall.Kill(syscall.Getpid(), syscall.SIGTERM) + }) + + if enableProfiling { + mux.HandleFunc("/debug/pprof/", pprof.Index) + mux.HandleFunc("/debug/pprof/profile", pprof.Profile) + mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol) + mux.HandleFunc("/debug/pprof/trace", pprof.Trace) + } + + server := &http.Server{ + Addr: fmt.Sprintf(":%v", port), + Handler: mux, + } + glog.Fatal(server.ListenAndServe()) +} diff --git a/core/pkg/ingress/controller/metrics.go b/core/pkg/ingress/controller/metrics.go new file mode 100644 index 0000000000..1b22b5bed5 --- /dev/null +++ b/core/pkg/ingress/controller/metrics.go @@ -0,0 +1,60 @@ +/* +Copyright 2015 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 controller + +import "github.com/prometheus/client_golang/prometheus" + +const ( + ns = "ingress_controller" + operation = "count" + reloadLabel = "reloads" +) + +func init() { + prometheus.MustRegister(reloadOperation) + prometheus.MustRegister(reloadOperationErrors) + + reloadOperationErrors.WithLabelValues(reloadLabel).Set(0) + reloadOperation.WithLabelValues(reloadLabel).Set(0) +} + +var ( + reloadOperation = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Namespace: ns, + Name: "success", + Help: "Cumulative number of Ingress controller reload operations", + }, + []string{operation}, + ) + reloadOperationErrors = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Namespace: ns, + Name: "errors", + Help: "Cumulative number of Ingress controller errors during reload operations", + }, + []string{operation}, + ) +) + +func incReloadCount() { + reloadOperation.WithLabelValues(reloadLabel).Inc() +} + +func incReloadErrorCount() { + reloadOperationErrors.WithLabelValues(reloadLabel).Inc() +} diff --git a/core/pkg/ingress/controller/named_port.go b/core/pkg/ingress/controller/named_port.go new file mode 100644 index 0000000000..1b9a09dc4b --- /dev/null +++ b/core/pkg/ingress/controller/named_port.go @@ -0,0 +1,105 @@ +/* +Copyright 2015 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 controller + +import ( + "encoding/json" + "fmt" + "reflect" + "strconv" + + "github.com/golang/glog" + + "k8s.io/ingress/core/pkg/ingress/annotations/service" + + "k8s.io/kubernetes/pkg/api" + podutil "k8s.io/kubernetes/pkg/api/pod" + "k8s.io/kubernetes/pkg/labels" +) + +// checkSvcForUpdate verifies if one of the running pods for a service contains +// named port. If the annotation in the service does not exists or is not equals +// to the port mapping obtained from the pod the service must be updated to reflect +// the current state +func (ic *GenericController) checkSvcForUpdate(svc *api.Service) error { + // get the pods associated with the service + // TODO: switch this to a watch + pods, err := ic.cfg.Client.Pods(svc.Namespace).List(api.ListOptions{ + LabelSelector: labels.Set(svc.Spec.Selector).AsSelector(), + }) + + if err != nil { + return fmt.Errorf("error searching service pods %v/%v: %v", svc.Namespace, svc.Name, err) + } + + if len(pods.Items) == 0 { + return nil + } + + namedPorts := map[string]string{} + + // we need to check only one pod searching for named ports + pod := &pods.Items[0] + glog.V(4).Infof("checking pod %v/%v for named port information", pod.Namespace, pod.Name) + for i := range svc.Spec.Ports { + servicePort := &svc.Spec.Ports[i] + + _, err := strconv.Atoi(servicePort.TargetPort.StrVal) + if err != nil { + portNum, err := podutil.FindPort(pod, servicePort) + if err != nil { + glog.V(4).Infof("failed to find port for service %s/%s: %v", portNum, svc.Namespace, svc.Name, err) + continue + } + + if servicePort.TargetPort.StrVal == "" { + continue + } + + namedPorts[servicePort.TargetPort.StrVal] = fmt.Sprintf("%v", portNum) + } + } + + if svc.ObjectMeta.Annotations == nil { + svc.ObjectMeta.Annotations = map[string]string{} + } + + curNamedPort := svc.ObjectMeta.Annotations[service.NamedPortAnnotation] + if len(namedPorts) > 0 && !reflect.DeepEqual(curNamedPort, namedPorts) { + data, _ := json.Marshal(namedPorts) + + newSvc, err := ic.cfg.Client.Services(svc.Namespace).Get(svc.Name) + if err != nil { + return fmt.Errorf("error getting service %v/%v: %v", svc.Namespace, svc.Name, err) + } + + if newSvc.ObjectMeta.Annotations == nil { + newSvc.ObjectMeta.Annotations = map[string]string{} + } + + newSvc.ObjectMeta.Annotations[service.NamedPortAnnotation] = string(data) + glog.Infof("updating service %v with new named port mappings", svc.Name) + _, err = ic.cfg.Client.Services(svc.Namespace).Update(newSvc) + if err != nil { + return fmt.Errorf("error syncing service %v/%v: %v", svc.Namespace, svc.Name, err) + } + + return nil + } + + return nil +} diff --git a/core/pkg/ingress/controller/util.go b/core/pkg/ingress/controller/util.go new file mode 100644 index 0000000000..68dafb6d76 --- /dev/null +++ b/core/pkg/ingress/controller/util.go @@ -0,0 +1,95 @@ +/* +Copyright 2015 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 controller + +import ( + "strings" + + "k8s.io/ingress/core/pkg/ingress" + "k8s.io/ingress/core/pkg/ingress/annotations/parser" + + "k8s.io/kubernetes/pkg/apis/extensions" +) + +// newDefaultServer return an UpstreamServer to be use as default server that returns 503. +func newDefaultServer() ingress.UpstreamServer { + return ingress.UpstreamServer{Address: "127.0.0.1", Port: "8181"} +} + +// newUpstream creates an upstream without servers. +func newUpstream(name string) *ingress.Upstream { + return &ingress.Upstream{ + Name: name, + Backends: []ingress.UpstreamServer{}, + } +} + +func isHostValid(host string, cert *ingress.SSLCert) bool { + if cert == nil { + return false + } + for _, cn := range cert.CN { + if matchHostnames(cn, host) { + return true + } + } + + return false +} + +func matchHostnames(pattern, host string) bool { + host = strings.TrimSuffix(host, ".") + pattern = strings.TrimSuffix(pattern, ".") + + if len(pattern) == 0 || len(host) == 0 { + return false + } + + patternParts := strings.Split(pattern, ".") + hostParts := strings.Split(host, ".") + + if len(patternParts) != len(hostParts) { + return false + } + + for i, patternPart := range patternParts { + if i == 0 && patternPart == "*" { + continue + } + if patternPart != hostParts[i] { + return false + } + } + + return true +} + +// IsValidClass returns true if the given Ingress either doesn't specify +// the ingress.class annotation, or it's set to the configured in the +// ingress controller. +func IsValidClass(ing *extensions.Ingress, class string) bool { + if class == "" { + return true + } + + cc, _ := parser.GetStringAnnotation(ingressClassKey, ing) + if cc == "" { + return true + } + + return cc == class +} diff --git a/core/pkg/ingress/controller/util_test.go b/core/pkg/ingress/controller/util_test.go new file mode 100644 index 0000000000..ba19ea8304 --- /dev/null +++ b/core/pkg/ingress/controller/util_test.go @@ -0,0 +1,50 @@ +/* +Copyright 2015 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 controller + +import ( + "testing" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/apis/extensions" +) + +func TestIsValidClass(t *testing.T) { + ing := &extensions.Ingress{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Namespace: api.NamespaceDefault, + }, + } + + b := IsValidClass(ing, "") + if !b { + t.Error("Expected a valid class (missing annotation)") + } + + data := map[string]string{} + data[ingressClassKey] = "custom" + ing.SetAnnotations(data) + b = IsValidClass(ing, "custom") + if !b { + t.Errorf("Expected valid class but %v returned", b) + } + b = IsValidClass(ing, "nginx") + if b { + t.Errorf("Expected invalid class but %v returned", b) + } +} diff --git a/core/pkg/ingress/defaults/main.go b/core/pkg/ingress/defaults/main.go new file mode 100644 index 0000000000..9c85ba4046 --- /dev/null +++ b/core/pkg/ingress/defaults/main.go @@ -0,0 +1,60 @@ +package defaults + +// Backend defines the mandatory configuration that an Ingress controller must provide +// The reason of this requirements is the annotations are generic. If some implementation do not supports +// one or more annotations it just can provides defaults +type Backend struct { + // enables which HTTP codes should be passed for processing with the error_page directive + // http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_intercept_errors + // http://nginx.org/en/docs/http/ngx_http_core_module.html#error_page + // By default this is disabled + CustomHTTPErrors []int `structs:"custom-http-errors,-"` + + // Defines a timeout for establishing a connection with a proxied server. + // It should be noted that this timeout cannot usually exceed 75 seconds. + // http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_connect_timeout + ProxyConnectTimeout int `structs:"proxy-connect-timeout"` + + // Timeout in seconds for reading a response from the proxied server. The timeout is set only between + // two successive read operations, not for the transmission of the whole response + // http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_read_timeout + ProxyReadTimeout int `structs:"proxy-read-timeout"` + + // Timeout in seconds for transmitting a request to the proxied server. The timeout is set only between + // two successive write operations, not for the transmission of the whole request. + // http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_send_timeout + ProxySendTimeout int `structs:"proxy-send-timeout"` + + // Sets the size of the buffer used for reading the first part of the response received from the + // proxied server. This part usually contains a small response header. + // http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size) + ProxyBufferSize string `structs:"proxy-buffer-size"` + + // Configures name servers used to resolve names of upstream servers into addresses + // http://nginx.org/en/docs/http/ngx_http_core_module.html#resolver + Resolver string `structs:"resolver"` + + // SkipAccessLogURLs sets a list of URLs that should not appear in the NGINX access log + // This is useful with urls like `/health` or `health-check` that make "complex" reading the logs + // By default this list is empty + SkipAccessLogURLs []string `structs:"skip-access-log-urls,-"` + + // Enables or disables the redirect (301) to the HTTPS port + SSLRedirect bool `structs:"ssl-redirect"` + + // Number of unsuccessful attempts to communicate with the server that should happen in the + // duration set by the fail_timeout parameter to consider the server unavailable + // http://nginx.org/en/docs/http/ngx_http_upstream_module.html#upstream + // Default: 0, ie use platform liveness probe + UpstreamMaxFails int `structs:"upstream-max-fails"` + + // Time during which the specified number of unsuccessful attempts to communicate with + // the server should happen to consider the server unavailable + // http://nginx.org/en/docs/http/ngx_http_upstream_module.html#upstream + // Default: 0, ie use platform liveness probe + UpstreamFailTimeout int `structs:"upstream-fail-timeout"` + + // WhitelistSourceRange allows limiting access to certain client addresses + // http://nginx.org/en/docs/http/ngx_http_access_module.html + WhitelistSourceRange []string `structs:"whitelist-source-range,-"` +} diff --git a/core/pkg/ingress/status/election.go b/core/pkg/ingress/status/election.go new file mode 100644 index 0000000000..0710f1d825 --- /dev/null +++ b/core/pkg/ingress/status/election.go @@ -0,0 +1,119 @@ +/* +Copyright 2015 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 status + +import ( + "encoding/json" + "os" + "time" + + "github.com/golang/glog" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/errors" + client "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" + "k8s.io/kubernetes/pkg/client/leaderelection" + "k8s.io/kubernetes/pkg/client/leaderelection/resourcelock" + "k8s.io/kubernetes/pkg/client/record" +) + +func getCurrentLeader(electionID, namespace string, c client.Interface) (string, *api.Endpoints, error) { + endpoints, err := c.Core().Endpoints(namespace).Get(electionID) + if err != nil { + return "", nil, err + } + val, found := endpoints.Annotations[resourcelock.LeaderElectionRecordAnnotationKey] + if !found { + return "", endpoints, nil + } + electionRecord := resourcelock.LeaderElectionRecord{} + if err = json.Unmarshal([]byte(val), &electionRecord); err != nil { + return "", nil, err + } + return electionRecord.HolderIdentity, endpoints, err +} + +// NewElection creates an election. 'namespace'/'election' should be an existing Kubernetes Service +// 'id' is the id if this leader, should be unique. +func NewElection(electionID, + id, + namespace string, + ttl time.Duration, + callback func(leader string), + c client.Interface) (*leaderelection.LeaderElector, error) { + + _, err := c.Core().Endpoints(namespace).Get(electionID) + if err != nil { + if errors.IsNotFound(err) { + _, err = c.Core().Endpoints(namespace).Create(&api.Endpoints{ + ObjectMeta: api.ObjectMeta{ + Name: electionID, + }, + }) + if err != nil && !errors.IsConflict(err) { + return nil, err + } + } else { + return nil, err + } + } + + callbacks := leaderelection.LeaderCallbacks{ + OnStartedLeading: func(stop <-chan struct{}) { + callback(id) + }, + OnStoppedLeading: func() { + leader, _, err := getCurrentLeader(electionID, namespace, c) + if err != nil { + glog.Errorf("failed to get leader: %v", err) + // empty string means leader is unknown + callback("") + return + } + callback(leader) + }, + } + + broadcaster := record.NewBroadcaster() + hostname, err := os.Hostname() + if err != nil { + return nil, err + } + recorder := broadcaster.NewRecorder(api.EventSource{ + Component: "ingress-leader-elector", + Host: hostname, + }) + + lock := resourcelock.EndpointsLock{ + EndpointsMeta: api.ObjectMeta{Namespace: namespace, Name: electionID}, + Client: c, + LockConfig: resourcelock.ResourceLockConfig{ + Identity: id, + EventRecorder: recorder, + }, + } + + config := leaderelection.LeaderElectionConfig{ + Lock: &lock, + LeaseDuration: ttl, + RenewDeadline: ttl / 2, + RetryPeriod: ttl / 4, + Callbacks: callbacks, + } + + return leaderelection.NewLeaderElector(config) +} diff --git a/core/pkg/ingress/status/status.go b/core/pkg/ingress/status/status.go new file mode 100644 index 0000000000..f454beb69d --- /dev/null +++ b/core/pkg/ingress/status/status.go @@ -0,0 +1,283 @@ +/* +Copyright 2015 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 status + +import ( + "sort" + "sync" + "time" + + "github.com/golang/glog" + + cache_store "k8s.io/ingress/core/pkg/cache" + "k8s.io/ingress/core/pkg/k8s" + strings "k8s.io/ingress/core/pkg/strings" + "k8s.io/ingress/core/pkg/task" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/apis/extensions" + clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" + "k8s.io/kubernetes/pkg/client/leaderelection" + "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/util/wait" +) + +const ( + updateInterval = 30 * time.Second +) + +// Sync ... +type Sync interface { + Run(stopCh <-chan struct{}) + Shutdown() +} + +// Config ... +type Config struct { + Client clientset.Interface + PublishService string + IngressLister cache_store.StoreToIngressLister +} + +// statusSync keeps the status IP in each Ingress rule updated executing a periodic check +// in all the defined rules. To simplify the process leader election is used so the update +// is executed only in one node (Ingress controllers can be scaled to more than one) +// If the controller is running with the flag --publish-service (with a valid service) +// the IP address behind the service is used, if not the source is the IP/s of the node/s +type statusSync struct { + Config + // pod contains runtime information about this pod + pod *k8s.PodInfo + + elector *leaderelection.LeaderElector + // workqueue used to keep in sync the status IP/s + // in the Ingress rules + syncQueue *task.Queue + + runLock *sync.Mutex +} + +// Run starts the loop to keep the status in sync +func (s statusSync) Run(stopCh <-chan struct{}) { + go wait.Forever(s.elector.Run, 0) + go s.run() + + go s.syncQueue.Run(time.Second, stopCh) + + <-stopCh +} + +// Shutdown stop the sync. In case the instance is the leader it will remove the current IP +// if there is no other instances running. +func (s statusSync) Shutdown() { + go s.syncQueue.Shutdown() + // remove IP from Ingress + if !s.elector.IsLeader() { + return + } + + glog.Infof("updating status of Ingress rules (remove)") + + ips, err := s.getRunningIPs() + if err != nil { + glog.Errorf("error obtaining running IPs: %v", ips) + return + } + + if len(ips) > 1 { + // leave the job to the next leader + glog.Infof("leaving status update for next leader (%v)", len(ips)) + return + } + + glog.Infof("removing my ip (%v)", ips) + s.updateStatus([]api.LoadBalancerIngress{}) +} + +func (s *statusSync) run() { + err := wait.PollInfinite(updateInterval, func() (bool, error) { + if s.syncQueue.IsShuttingDown() { + return true, nil + } + // send a dummy object to the queue to force a sync + s.syncQueue.Enqueue("dummy") + return false, nil + }) + if err != nil { + glog.Errorf("error waiting shutdown: %v", err) + } +} + +func (s *statusSync) sync(key interface{}) error { + s.runLock.Lock() + defer s.runLock.Unlock() + + if !s.elector.IsLeader() { + glog.V(2).Infof("skipping Ingress status update (I am not the current leader)") + return nil + } + + ips, err := s.getRunningIPs() + if err != nil { + return err + } + s.updateStatus(sliceToStatus(ips)) + + return nil +} + +// callback invoked function when a new leader is elected +func (s *statusSync) callback(leader string) { + if s.syncQueue.IsShuttingDown() { + return + } + + glog.V(2).Infof("new leader elected (%v)", leader) + if leader == s.pod.Name { + glog.V(2).Infof("I am the new status update leader") + } +} + +func (s statusSync) keyfunc(input interface{}) (interface{}, error) { + return input, nil +} + +// NewStatusSyncer returns a new Sync instance +func NewStatusSyncer(config Config) Sync { + pod, err := k8s.GetPodDetails(config.Client) + if err != nil { + glog.Fatalf("unexpected error obtaining pod information: %v", err) + } + + st := statusSync{ + pod: pod, + runLock: &sync.Mutex{}, + Config: config, + } + st.syncQueue = task.NewCustomTaskQueue(st.sync, st.keyfunc) + + le, err := NewElection("ingress-controller-leader", + pod.Name, pod.Namespace, 30*time.Second, + st.callback, config.Client) + if err != nil { + glog.Fatalf("unexpected error starting leader election: %v", err) + } + st.elector = le + return st +} + +func (s *statusSync) getRunningIPs() ([]string, error) { + if s.PublishService != "" { + ns, name, _ := k8s.ParseNameNS(s.PublishService) + svc, err := s.Client.Core().Services(ns).Get(name) + if err != nil { + return nil, err + } + + ips := []string{} + for _, ip := range svc.Status.LoadBalancer.Ingress { + ips = append(ips, ip.IP) + } + + return ips, nil + } + + // get information about all the pods running the ingress controller + pods, err := s.Client.Core().Pods(s.pod.Namespace).List(api.ListOptions{ + LabelSelector: labels.SelectorFromSet(s.pod.Labels), + }) + if err != nil { + return nil, err + } + + ips := []string{} + for _, pod := range pods.Items { + if !strings.StringInSlice(pod.Status.HostIP, ips) { + ips = append(ips, pod.Status.HostIP) + } + } + return ips, nil +} + +func sliceToStatus(ips []string) []api.LoadBalancerIngress { + lbi := []api.LoadBalancerIngress{} + for _, ip := range ips { + lbi = append(lbi, api.LoadBalancerIngress{IP: ip}) + } + + sort.Sort(loadBalancerIngressByIP(lbi)) + return lbi +} + +func (s *statusSync) updateStatus(newIPs []api.LoadBalancerIngress) { + ings := s.IngressLister.List() + var wg sync.WaitGroup + wg.Add(len(ings)) + for _, cur := range ings { + ing := cur.(*extensions.Ingress) + go func(wg *sync.WaitGroup) { + defer wg.Done() + ingClient := s.Client.Extensions().Ingresses(ing.Namespace) + currIng, err := ingClient.Get(ing.Name) + if err != nil { + glog.Errorf("unexpected error searching Ingress %v/%v: %v", ing.Namespace, ing.Name, err) + return + } + + curIPs := ing.Status.LoadBalancer.Ingress + sort.Sort(loadBalancerIngressByIP(curIPs)) + if ingressSliceEqual(newIPs, curIPs) { + glog.V(3).Infof("skipping update of Ingress %v/%v (there is no change)", currIng.Namespace, currIng.Name) + return + } + + glog.Infof("updating Ingress %v/%v status to %v", currIng.Namespace, currIng.Name, newIPs) + currIng.Status.LoadBalancer.Ingress = newIPs + _, err = ingClient.UpdateStatus(currIng) + if err != nil { + glog.Warningf("error updating ingress rule: %v", err) + } + }(&wg) + } + + wg.Wait() +} + +func ingressSliceEqual(lhs, rhs []api.LoadBalancerIngress) bool { + if len(lhs) != len(rhs) { + return false + } + + for i := range lhs { + if lhs[i].IP != rhs[i].IP { + return false + } + if lhs[i].Hostname != rhs[i].Hostname { + return false + } + } + return true +} + +// loadBalancerIngressByIP sorts LoadBalancerIngress using the field IP +type loadBalancerIngressByIP []api.LoadBalancerIngress + +func (c loadBalancerIngressByIP) Len() int { return len(c) } +func (c loadBalancerIngressByIP) Swap(i, j int) { c[i], c[j] = c[j], c[i] } +func (c loadBalancerIngressByIP) Less(i, j int) bool { + return c[i].IP < c[j].IP +} diff --git a/core/pkg/ingress/types.go b/core/pkg/ingress/types.go new file mode 100644 index 0000000000..5eb83670e9 --- /dev/null +++ b/core/pkg/ingress/types.go @@ -0,0 +1,214 @@ +/* +Copyright 2015 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 ingress + +import ( + "os/exec" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" + + "k8s.io/ingress/core/pkg/ingress/annotations/auth" + "k8s.io/ingress/core/pkg/ingress/annotations/authreq" + "k8s.io/ingress/core/pkg/ingress/annotations/authtls" + "k8s.io/ingress/core/pkg/ingress/annotations/ipwhitelist" + "k8s.io/ingress/core/pkg/ingress/annotations/proxy" + "k8s.io/ingress/core/pkg/ingress/annotations/ratelimit" + "k8s.io/ingress/core/pkg/ingress/annotations/rewrite" + "k8s.io/ingress/core/pkg/ingress/defaults" +) + +var ( + // DefaultSSLDirectory defines the location where the SSL certificates will be generated + DefaultSSLDirectory = "/ingress-controller/ssl" +) + +// Controller ... +type Controller interface { + // Start returns the command is executed to start the backend. + // The command must run in foreground. + Start() + // Stop stops the backend + Stop() error + // Restart reload the backend with the a configuration file returning + // the combined output of Stdout and Stderr + Restart(data []byte) ([]byte, error) + // Tests returns a commands that checks if the configuration file is valid + // Example: nginx -t -c + Test(file string) *exec.Cmd + // OnUpdate callback invoked from the sync queue https://k8s.io/ingress/core/blob/master/pkg/ingress/controller/controller.go#L355 + // when an update occurs. This is executed frequently because Ingress + // controllers watches changes in: + // - Ingresses: main work + // - Secrets: referenced from Ingress rules with TLS configured + // - ConfigMaps: where the controller reads custom configuration + // - Services: referenced from Ingress rules and required to obtain + // information about ports and annotations + // - Endpoints: referenced from Services and what the backend uses + // to route traffic + // + // ConfigMap content of --configmap + // Configuration returns the translation from Ingress rules containing + // information about all the upstreams (service endpoints ) "virtual" + // servers (FQDN) + // and all the locations inside each server. Each location contains + // information about all the annotations were configured + // https://k8s.io/ingress/core/blob/master/pkg/ingress/types.go#L48 + OnUpdate(*api.ConfigMap, Configuration) ([]byte, error) + // UpstreamDefaults returns the minimum settings required to configure the + // communication to upstream servers (endpoints) + UpstreamDefaults() defaults.Backend + // IsReloadRequired checks if the backend must be reloaded or not. + // The parameter contains the new rendered template + IsReloadRequired([]byte) bool + // Info returns information about the ingress controller + // This can include build version, repository, etc. + Info() string +} + +// Configuration describes +type Configuration struct { + HealthzURL string + Upstreams []*Upstream + Servers []*Server + TCPUpstreams []*Location + UDPUpstreams []*Location + PassthroughUpstreams []*SSLPassthroughUpstreams +} + +// Upstream describes an upstream server (endpoint) +type Upstream struct { + // Secure indicates if the communication with the en + Secure bool + // Name represents an unique api.Service name formatted + // as -- + Name string + // Backends + Backends []UpstreamServer +} + +// SSLPassthroughUpstreams describes an SSL upstream server configured +// as passthrough (no TLS termination) +type SSLPassthroughUpstreams struct { + Upstream + + Host string +} + +// UpstreamByNameServers sorts upstreams by name +type UpstreamByNameServers []*Upstream + +func (c UpstreamByNameServers) Len() int { return len(c) } +func (c UpstreamByNameServers) Swap(i, j int) { c[i], c[j] = c[j], c[i] } +func (c UpstreamByNameServers) Less(i, j int) bool { + return c[i].Name < c[j].Name +} + +// UpstreamServer describes a server in an upstream +type UpstreamServer struct { + // Address IP address of the endpoint + Address string + Port string + // MaxFails returns the maximum number of check failures + // allowed before this should be considered dow. + // Setting 0 indicates that the check is performed by a Kubernetes probe + MaxFails int + FailTimeout int +} + +// Server describes a virtual server +type Server struct { + Name string + SSL bool + SSLPassthrough bool + SSLCertificate string + //SSLCertificateKey string + SSLPemChecksum string + Locations []*Location +} + +// Location describes a server location +type Location struct { + IsDefBackend bool + SecureUpstream bool + EnableCORS bool + Path string + Upstream Upstream + BasicDigestAuth auth.BasicDigest + RateLimit ratelimit.RateLimit + Redirect rewrite.Redirect + Whitelist ipwhitelist.SourceRange + ExternalAuth authreq.External + Proxy proxy.Configuration + CertificateAuth authtls.SSLCert +} + +// UpstreamServerByAddrPort sorts upstream servers by address and port +type UpstreamServerByAddrPort []UpstreamServer + +func (c UpstreamServerByAddrPort) Len() int { return len(c) } +func (c UpstreamServerByAddrPort) Swap(i, j int) { c[i], c[j] = c[j], c[i] } +func (c UpstreamServerByAddrPort) Less(i, j int) bool { + iName := c[i].Address + jName := c[j].Address + if iName != jName { + return iName < jName + } + + iU := c[i].Port + jU := c[j].Port + return iU < jU +} + +// ServerByName sorts server by name +type ServerByName []*Server + +func (c ServerByName) Len() int { return len(c) } +func (c ServerByName) Swap(i, j int) { c[i], c[j] = c[j], c[i] } +func (c ServerByName) Less(i, j int) bool { + return c[i].Name < c[j].Name +} + +// LocationByPath sorts location by path +// Location / is the last one +type LocationByPath []*Location + +func (c LocationByPath) Len() int { return len(c) } +func (c LocationByPath) Swap(i, j int) { c[i], c[j] = c[j], c[i] } +func (c LocationByPath) Less(i, j int) bool { + return c[i].Path > c[j].Path +} + +// SSLCert describes a SSL certificate to be used in a server +type SSLCert struct { + api.ObjectMeta + + //CertFileName string + //KeyFileName string + CAFileName string + + // PemFileName contains the path to the file with the certificate and key concatenated + PemFileName string + // PemSHA contains the sha1 of the pem file. + // This is used to detect changes in the secret that contains the certificates + PemSHA string + // CN contains all the common names defined in the SSL certificate + CN []string +} + +// GetObjectKind implements the ObjectKind interface as a noop +func (s SSLCert) GetObjectKind() unversioned.ObjectKind { return unversioned.EmptyObjectKind } diff --git a/core/pkg/k8s/main.go b/core/pkg/k8s/main.go new file mode 100644 index 0000000000..2f0caf5e52 --- /dev/null +++ b/core/pkg/k8s/main.go @@ -0,0 +1,110 @@ +/* +Copyright 2015 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 k8s + +import ( + "fmt" + "os" + "strings" + + "k8s.io/kubernetes/pkg/api" + clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" +) + +// IsValidService checks if exists a service with the specified name +func IsValidService(kubeClient clientset.Interface, name string) (*api.Service, error) { + ns, name, err := ParseNameNS(name) + if err != nil { + return nil, err + } + return kubeClient.Core().Services(ns).Get(name) +} + +// IsValidSecret checks if exists a secret with the specified name +func IsValidSecret(kubeClient clientset.Interface, name string) (*api.Secret, error) { + ns, name, err := ParseNameNS(name) + if err != nil { + return nil, err + } + return kubeClient.Core().Secrets(ns).Get(name) +} + +// ParseNameNS parses a string searching a namespace and name +func ParseNameNS(input string) (string, string, error) { + nsName := strings.Split(input, "/") + if len(nsName) != 2 { + return "", "", fmt.Errorf("invalid format (namespace/name) found in '%v'", input) + } + + return nsName[0], nsName[1], nil +} + +// GetNodeIP returns the IP address of a node in the cluster +func GetNodeIP(kubeClient clientset.Interface, name string) string { + var externalIP string + node, err := kubeClient.Core().Nodes().Get(name) + if err != nil { + return externalIP + } + + for _, address := range node.Status.Addresses { + if address.Type == api.NodeExternalIP { + if address.Address != "" { + externalIP = address.Address + break + } + } + + if externalIP == "" && address.Type == api.NodeLegacyHostIP { + externalIP = address.Address + } + } + return externalIP +} + +// PodInfo contains runtime information about the pod running the Ingres controller +type PodInfo struct { + Name string + Namespace string + NodeIP string + // Labels selectors of the running pod + // This is used to search for other Ingress controller pods + Labels map[string]string +} + +// GetPodDetails returns runtime information about the pod: +// name, namespace and IP of the node where it is running +func GetPodDetails(kubeClient clientset.Interface) (*PodInfo, error) { + podName := os.Getenv("POD_NAME") + podNs := os.Getenv("POD_NAMESPACE") + + if podName == "" && podNs == "" { + return nil, fmt.Errorf("unable to get POD information (missing POD_NAME or POD_NAMESPACE environment variable") + } + + pod, _ := kubeClient.Core().Pods(podNs).Get(podName) + if pod == nil { + return nil, fmt.Errorf("unable to get POD information") + } + + return &PodInfo{ + Name: podName, + Namespace: podNs, + NodeIP: GetNodeIP(kubeClient, pod.Spec.NodeName), + Labels: pod.GetLabels(), + }, nil +} diff --git a/core/pkg/k8s/main_test.go b/core/pkg/k8s/main_test.go new file mode 100644 index 0000000000..fa9cce573e --- /dev/null +++ b/core/pkg/k8s/main_test.go @@ -0,0 +1,116 @@ +/* +Copyright 2015 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 k8s + +import ( + "testing" + + "k8s.io/kubernetes/pkg/api" + testclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake" +) + +func TestParseNameNS(t *testing.T) { + + tests := []struct { + title string + input string + ns string + name string + expErr bool + }{ + {"empty string", "", "", "", true}, + {"demo", "demo", "", "", true}, + {"kube-system", "kube-system", "", "", true}, + {"default/kube-system", "default/kube-system", "default", "kube-system", false}, + } + + for _, test := range tests { + ns, name, err := ParseNameNS(test.input) + if test.expErr { + if err == nil { + t.Errorf("%v: expected error but retuned nil", test.title) + } + continue + } + if test.ns != ns { + t.Errorf("%v: expected %v but retuned %v", test.title, test.ns, ns) + } + if test.name != name { + t.Errorf("%v: expected %v but retuned %v", test.title, test.name, name) + } + } +} + +func TestIsValidService(t *testing.T) { + fk := testclient.NewSimpleClientset(&api.Service{ + ObjectMeta: api.ObjectMeta{ + Namespace: api.NamespaceDefault, + Name: "demo", + }, + }) + + _, err := IsValidService(fk, "") + if err == nil { + t.Errorf("expected error but retuned nil") + } + s, err := IsValidService(fk, "default/demo") + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if s == nil { + t.Errorf("expected a Service but retuned nil") + } + + fk = testclient.NewSimpleClientset() + s, err = IsValidService(fk, "default/demo") + if err == nil { + t.Errorf("expected an error but retuned nil") + } + if s != nil { + t.Errorf("unexpected Service returned: %v", s) + } +} + +func TestIsValidSecret(t *testing.T) { + fk := testclient.NewSimpleClientset(&api.Secret{ + ObjectMeta: api.ObjectMeta{ + Namespace: api.NamespaceDefault, + Name: "demo", + }, + }) + + _, err := IsValidSecret(fk, "") + if err == nil { + t.Errorf("expected error but retuned nil") + } + s, err := IsValidSecret(fk, "default/demo") + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if s == nil { + t.Errorf("expected a Secret but retuned nil") + } + + fk = testclient.NewSimpleClientset() + s, err = IsValidSecret(fk, "default/demo") + if err == nil { + t.Errorf("expected an error but retuned nil") + } + if s != nil { + t.Errorf("unexpected Secret returned: %v", s) + } +} diff --git a/core/pkg/net/dns/dns.go b/core/pkg/net/dns/dns.go new file mode 100644 index 0000000000..1988d987c4 --- /dev/null +++ b/core/pkg/net/dns/dns.go @@ -0,0 +1,52 @@ +/* +Copyright 2015 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 dns + +import ( + "io/ioutil" + "strings" + + "github.com/golang/glog" +) + +// GetSystemNameServers returns the list of nameservers located in the file /etc/resolv.conf +func GetSystemNameServers() ([]string, error) { + var nameservers []string + file, err := ioutil.ReadFile("/etc/resolv.conf") + if err != nil { + return nameservers, err + } + + // Lines of the form "nameserver 1.2.3.4" accumulate. + lines := strings.Split(string(file), "\n") + for l := range lines { + trimmed := strings.TrimSpace(lines[l]) + if strings.HasPrefix(trimmed, "#") { + continue + } + fields := strings.Fields(trimmed) + if len(fields) == 0 { + continue + } + if fields[0] == "nameserver" { + nameservers = append(nameservers, fields[1:]...) + } + } + + glog.V(3).Infof("nameservers to use: %v", nameservers) + return nameservers, nil +} diff --git a/core/pkg/net/dns/dns_test.go b/core/pkg/net/dns/dns_test.go new file mode 100644 index 0000000000..488929e880 --- /dev/null +++ b/core/pkg/net/dns/dns_test.go @@ -0,0 +1,31 @@ +/* +Copyright 2015 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 dns + +import ( + "testing" +) + +func TestGetDNSServers(t *testing.T) { + s, err := GetSystemNameServers() + if err != nil { + t.Fatalf("unexpected error reading /etc/resolv.conf file: %v", err) + } + if len(s) < 1 { + t.Error("expected at least 1 nameserver in /etc/resolv.conf") + } +} diff --git a/core/pkg/net/ssl/ssl.go b/core/pkg/net/ssl/ssl.go new file mode 100644 index 0000000000..a9722fc76f --- /dev/null +++ b/core/pkg/net/ssl/ssl.go @@ -0,0 +1,179 @@ +/* +Copyright 2015 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 ssl + +import ( + "crypto/sha1" + "crypto/x509" + "encoding/hex" + "encoding/pem" + "fmt" + "io/ioutil" + "os" + + "github.com/golang/glog" + + "k8s.io/ingress/core/pkg/ingress" +) + +// AddOrUpdateCertAndKey creates a .pem file wth the cert and the key with the specified name +func AddOrUpdateCertAndKey(name string, cert, key, ca []byte) (*ingress.SSLCert, error) { + pemName := fmt.Sprintf("%v.pem", name) + pemFileName := fmt.Sprintf("%v/%v", ingress.DefaultSSLDirectory, pemName) + + tempPemFile, err := ioutil.TempFile("", pemName) + if err != nil { + return nil, fmt.Errorf("could not create temp pem file %v: %v", tempPemFile.Name(), err) + } + + _, err = tempPemFile.Write(cert) + if err != nil { + return nil, fmt.Errorf("could not write to pem file %v: %v", tempPemFile.Name(), err) + } + _, err = tempPemFile.Write([]byte("\n")) + if err != nil { + return nil, fmt.Errorf("could not write to pem file %v: %v", tempPemFile.Name(), err) + } + _, err = tempPemFile.Write(key) + if err != nil { + return nil, fmt.Errorf("could not write to pem file %v: %v", tempPemFile.Name(), err) + } + + err = tempPemFile.Close() + if err != nil { + return nil, fmt.Errorf("could not close temp pem file %v: %v", tempPemFile.Name(), err) + } + + pemCerts, err := ioutil.ReadFile(tempPemFile.Name()) + if err != nil { + return nil, err + } + + pembBock, _ := pem.Decode(pemCerts) + if pembBock == nil { + return nil, fmt.Errorf("No valid PEM formatted block found") + } + + pemCert, err := x509.ParseCertificate(pembBock.Bytes) + if err != nil { + return nil, err + } + + cn := []string{pemCert.Subject.CommonName} + if len(pemCert.DNSNames) > 0 { + cn = append(cn, pemCert.DNSNames...) + } + + err = os.Rename(tempPemFile.Name(), pemFileName) + if err != nil { + return nil, fmt.Errorf("could not move temp pem file %v to destination %v: %v", tempPemFile.Name(), pemFileName, err) + } + + if len(ca) > 0 { + bundle := x509.NewCertPool() + bundle.AppendCertsFromPEM(ca) + opts := x509.VerifyOptions{ + Roots: bundle, + } + + _, err := pemCert.Verify(opts) + if err != nil { + return nil, fmt.Errorf("failed to verify certificate chain: \n\t%s\n", err) + } + + caName := fmt.Sprintf("ca-%v.pem", name) + caFileName := fmt.Sprintf("%v/%v", ingress.DefaultSSLDirectory, caName) + f, err := os.Create(caFileName) + if err != nil { + return nil, fmt.Errorf("could not create ca pem file %v: %v", caFileName, err) + } + defer f.Close() + _, err = f.Write(ca) + if err != nil { + return nil, fmt.Errorf("could not create ca pem file %v: %v", caFileName, err) + } + f.Write([]byte("\n")) + + return &ingress.SSLCert{ + CAFileName: caFileName, + PemFileName: pemFileName, + PemSHA: pemSHA1(pemFileName), + CN: cn, + }, nil + } + + return &ingress.SSLCert{ + PemFileName: pemFileName, + PemSHA: pemSHA1(pemFileName), + CN: cn, + }, nil +} + +// SearchDHParamFile iterates all the secrets mounted inside the /etc/nginx-ssl directory +// in order to find a file with the name dhparam.pem. If such file exists it will +// returns the path. If not it just returns an empty string +func SearchDHParamFile(baseDir string) string { + files, _ := ioutil.ReadDir(baseDir) + for _, file := range files { + if !file.IsDir() { + continue + } + + dhPath := fmt.Sprintf("%v/%v/dhparam.pem", baseDir, file.Name()) + if _, err := os.Stat(dhPath); err == nil { + glog.Infof("using file '%v' for parameter ssl_dhparam", dhPath) + return dhPath + } + } + + glog.Warning("no file dhparam.pem found in secrets") + return "" +} + +// pemSHA1 returns the SHA1 of a pem file. This is used to +// reload NGINX in case a secret with a SSL certificate changed. +func pemSHA1(filename string) string { + hasher := sha1.New() + s, err := ioutil.ReadFile(filename) + if err != nil { + return "" + } + + hasher.Write(s) + return hex.EncodeToString(hasher.Sum(nil)) +} + +const ( + snakeOilPem = "/etc/ssl/certs/ssl-cert-snakeoil.pem" + snakeOilKey = "/etc/ssl/private/ssl-cert-snakeoil.key" +) + +// GetFakeSSLCert returns the snake oil ssl certificate created by the command +// make-ssl-cert generate-default-snakeoil --force-overwrite +func GetFakeSSLCert() ([]byte, []byte) { + cert, err := ioutil.ReadFile(snakeOilPem) + if err != nil { + return nil, nil + } + + key, err := ioutil.ReadFile(snakeOilKey) + if err != nil { + return nil, nil + } + + return cert, key +} diff --git a/controllers/nginx/nginx/ssl_test.go b/core/pkg/net/ssl/ssl_test.go similarity index 94% rename from controllers/nginx/nginx/ssl_test.go rename to core/pkg/net/ssl/ssl_test.go index 7cab68ce49..b4d3c5effa 100644 --- a/controllers/nginx/nginx/ssl_test.go +++ b/core/pkg/net/ssl/ssl_test.go @@ -14,20 +14,25 @@ See the License for the specific language governing permissions and limitations under the License. */ -package nginx +package ssl import ( "encoding/base64" "fmt" - "os" + "io/ioutil" "testing" "time" - "k8s.io/contrib/ingress/controllers/nginx/nginx/config" + "k8s.io/ingress/core/pkg/ingress" ) func TestAddOrUpdateCertAndKey(t *testing.T) { - config.SSLDirectory = os.TempDir() + td, err := ioutil.TempDir("", "ssl") + if err != nil { + t.Fatalf("Unexpected error creating temporal directory: %v", err) + } + ingress.DefaultSSLDirectory = td + // openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /tmp/tls.key -out /tmp/tls.crt -subj "/CN=echoheaders/O=echoheaders" tlsCrt := "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURhakNDQWxLZ0F3SUJBZ0lKQUxHUXR5VVBKTFhYTUEwR0NTcUdTSWIzRFFFQkJRVUFNQ3d4RkRBU0JnTlYKQkFNVEMyVmphRzlvWldGa1pYSnpNUlF3RWdZRFZRUUtFd3RsWTJodmFHVmhaR1Z5Y3pBZUZ3MHhOakF6TXpFeQpNekU1TkRoYUZ3MHhOekF6TXpFeU16RTVORGhhTUN3eEZEQVNCZ05WQkFNVEMyVmphRzlvWldGa1pYSnpNUlF3CkVnWURWUVFLRXd0bFkyaHZhR1ZoWkdWeWN6Q0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0MKZ2dFQkFONzVmS0N5RWwxanFpMjUxTlNabDYzeGQweG5HMHZTVjdYL0xxTHJveVNraW5nbnI0NDZZWlE4UEJWOAo5TUZzdW5RRGt1QVoyZzA3NHM1YWhLSm9BRGJOMzhld053RXNsVDJkRzhRTUw0TktrTUNxL1hWbzRQMDFlWG1PCmkxR2txZFA1ZUExUHlPZCtHM3gzZmxPN2xOdmtJdHVHYXFyc0tvMEhtMHhqTDVtRUpwWUlOa0tGSVhsWWVLZS8KeHRDR25CU2tLVHFMTG0yeExKSGFFcnJpaDZRdkx4NXF5U2gzZTU2QVpEcTlkTERvcWdmVHV3Z2IzekhQekc2NwppZ0E0dkYrc2FRNHpZUE1NMHQyU1NiVkx1M2pScWNvL3lxZysrOVJBTTV4bjRubnorL0hUWFhHKzZ0RDBaeGI1CmVVRDNQakVhTnlXaUV2dTN6UFJmdysyNURMY0NBd0VBQWFPQmpqQ0JpekFkQmdOVkhRNEVGZ1FVcktMZFhHeUUKNUlEOGRvd2lZNkdzK3dNMHFKc3dYQVlEVlIwakJGVXdVNEFVcktMZFhHeUU1SUQ4ZG93aVk2R3Mrd00wcUp1aApNS1F1TUN3eEZEQVNCZ05WQkFNVEMyVmphRzlvWldGa1pYSnpNUlF3RWdZRFZRUUtFd3RsWTJodmFHVmhaR1Z5CmM0SUpBTEdRdHlVUEpMWFhNQXdHQTFVZEV3UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUZCUUFEZ2dFQkFNZVMKMHFia3VZa3Z1enlSWmtBeE1PdUFaSDJCK0Evb3N4ODhFRHB1ckV0ZWN5RXVxdnRvMmpCSVdCZ2RkR3VBYU5jVQorUUZDRm9NakJOUDVWVUxIWVhTQ3VaczN2Y25WRDU4N3NHNlBaLzhzbXJuYUhTUjg1ZVpZVS80bmFyNUErdWErClIvMHJrSkZnOTlQSmNJd3JmcWlYOHdRcWdJVVlLNE9nWEJZcUJRL0VZS2YvdXl6UFN3UVZYRnVJTTZTeDBXcTYKTUNML3d2RlhLS0FaWDBqb3J4cHRjcldkUXNCcmYzWVRnYmx4TE1sN20zL2VuR1drcEhDUHdYeVRCOC9rRkw3SApLL2ZHTU1NWGswUkVSbGFPM1hTSUhrZUQ2SXJiRnRNV3R1RlJwZms2ZFA2TXlMOHRmTmZ6a3VvUHVEWUFaWllWCnR1NnZ0c0FRS0xWb0pGaGV0b1k9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K" tlsKey := "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBM3ZsOG9MSVNYV09xTGJuVTFKbVhyZkYzVEdjYlM5Slh0Zjh1b3V1akpLU0tlQ2V2CmpqcGhsRHc4Rlh6MHdXeTZkQU9TNEJuYURUdml6bHFFb21nQU5zM2Z4N0EzQVN5VlBaMGJ4QXd2ZzBxUXdLcjkKZFdqZy9UVjVlWTZMVWFTcDAvbDREVS9JNTM0YmZIZCtVN3VVMitRaTI0WnFxdXdxalFlYlRHTXZtWVFtbGdnMgpRb1VoZVZoNHA3L0cwSWFjRktRcE9vc3ViYkVza2RvU3V1S0hwQzh2SG1ySktIZDdub0JrT3IxMHNPaXFCOU83CkNCdmZNYy9NYnJ1S0FEaThYNnhwRGpOZzh3elMzWkpKdFV1N2VOR3B5ai9LcUQ3NzFFQXpuR2ZpZWZQNzhkTmQKY2I3cTBQUm5Gdmw1UVBjK01SbzNKYUlTKzdmTTlGL0Q3YmtNdHdJREFRQUJBb0lCQUViNmFEL0hMNjFtMG45bgp6bVkyMWwvYW83MUFmU0h2dlZnRCtWYUhhQkY4QjFBa1lmQUdpWlZrYjBQdjJRSFJtTERoaWxtb0lROWhadHVGCldQOVIxKythTFlnbGdmenZzanBBenR2amZTUndFaEFpM2pnSHdNY1p4S2Q3UnNJZ2hxY2huS093S0NYNHNNczQKUnBCbEFBZlhZWGs4R3F4NkxUbGptSDRDZk42QzZHM1EwTTlLMUxBN2lsck1Na3hwcngxMnBlVTNkczZMVmNpOQptOFdBL21YZ2I0c3pEbVNaWVpYRmNZMEhYNTgyS3JKRHpQWEVJdGQwZk5wd3I0eFIybzdzMEwvK2RnZCtqWERjCkh2SDBKZ3NqODJJaTIxWGZGM2tST3FxR3BKNmhVcncxTUZzVWRyZ29GL3pFck0vNWZKMDdVNEhodGFlalVzWTIKMFJuNXdpRUNnWUVBKzVUTVRiV084Wkg5K2pIdVQwc0NhZFBYcW50WTZYdTZmYU04Tm5CZWNoeTFoWGdlQVN5agpSWERlZGFWM1c0SjU5eWxIQ3FoOVdseVh4cDVTWWtyQU41RnQ3elFGYi91YmorUFIyWWhMTWZpYlBSYlYvZW1MCm5YaGF6MmtlNUUxT1JLY0x6QUVwSmpuZGQwZlZMZjdmQzFHeStnS2YyK3hTY1hjMHJqRE5iNGtDZ1lFQTR1UVEKQk91TlJQS3FKcDZUZS9zUzZrZitHbEpjQSs3RmVOMVlxM0E2WEVZVm9ydXhnZXQ4a2E2ZEo1QjZDOWtITGtNcQpwdnFwMzkxeTN3YW5uWC9ONC9KQlU2M2RxZEcyd1BWRUQ0REduaE54Qm1oaWZpQ1I0R0c2ZnE4MUV6ZE1vcTZ4CklTNHA2RVJaQnZkb1RqNk9pTHl6aUJMckpxeUhIMWR6c0hGRlNqOENnWUVBOWlSSEgyQ2JVazU4SnVYak8wRXcKUTBvNG4xdS9TZkQ4TFNBZ01VTVBwS1hpRTR2S0Qyd1U4a1BUNDFiWXlIZUh6UUpkdDFmU0RTNjZjR0ZHU1ZUSgphNVNsOG5yN051ejg3bkwvUmMzTGhFQ3Y0YjBOOFRjbW1oSy9CbDdiRXBOd0dFczNoNGs3TVdNOEF4QU15c3VxCmZmQ1pJM0tkNVJYNk0zbGwyV2QyRjhFQ2dZQlQ5RU9oTG0vVmhWMUVjUVR0cVZlMGJQTXZWaTVLSGozZm5UZkUKS0FEUVIvYVZncElLR3RLN0xUdGxlbVpPbi8yeU5wUS91UnpHZ3pDUUtldzNzU1RFSmMzYVlzbFVudzdhazJhZAp2ZTdBYXowMU84YkdHTk1oamNmdVBIS05LN2Nsc3pKRHJzcys4SnRvb245c0JHWEZYdDJuaWlpTTVPWVN5TTg4CkNJMjFEUUtCZ0hEQVRZbE84UWlDVWFBQlVqOFBsb1BtMDhwa3cyc1VmQW0xMzJCY00wQk9BN1hqYjhtNm1ManQKOUlteU5kZ2ZiM080UjlKVUxTb1pZSTc1dUxIL3k2SDhQOVlpWHZOdzMrTXl6VFU2b2d1YU8xSTNya2pna29NeAo5cU5pYlJFeGswS1A5MVZkckVLSEdHZEFwT05ES1N4VzF3ektvbUxHdmtYSTVKV05KRXFkCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==" @@ -43,10 +48,8 @@ func TestAddOrUpdateCertAndKey(t *testing.T) { t.Fatalf("Unexpected error: %+v", err) } - ngx := &Manager{} - name := fmt.Sprintf("test-%v", time.Now().UnixNano()) - ngxCert, err := ngx.AddOrUpdateCertAndKey(name, string(dCrt), string(dKey)) + ngxCert, err := AddOrUpdateCertAndKey(name, dCrt, dKey, []byte{}) if err != nil { t.Fatalf("unexpected error checking SSL certificate: %v", err) } diff --git a/core/pkg/strings/string.go b/core/pkg/strings/string.go new file mode 100644 index 0000000000..f866e6a461 --- /dev/null +++ b/core/pkg/strings/string.go @@ -0,0 +1,27 @@ +/* +Copyright 2015 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 strings + +// StringInSlice check whether string a is a member of slice. +func StringInSlice(a string, slice []string) bool { + for _, b := range slice { + if b == a { + return true + } + } + return false +} diff --git a/core/pkg/task/queue.go b/core/pkg/task/queue.go new file mode 100644 index 0000000000..e7fd0a848e --- /dev/null +++ b/core/pkg/task/queue.go @@ -0,0 +1,123 @@ +/* +Copyright 2015 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 task + +import ( + "fmt" + "time" + + "github.com/golang/glog" + + "k8s.io/kubernetes/pkg/client/cache" + "k8s.io/kubernetes/pkg/util/wait" + "k8s.io/kubernetes/pkg/util/workqueue" +) + +var ( + keyFunc = cache.DeletionHandlingMetaNamespaceKeyFunc +) + +// Queue manages a work queue through an independent worker that +// invokes the given sync function for every work item inserted. +type Queue struct { + // queue is the work queue the worker polls + queue workqueue.RateLimitingInterface + // sync is called for each item in the queue + sync func(interface{}) error + // workerDone is closed when the worker exits + workerDone chan struct{} + + fn func(obj interface{}) (interface{}, error) +} + +// Run ... +func (t *Queue) Run(period time.Duration, stopCh <-chan struct{}) { + wait.Until(t.worker, period, stopCh) +} + +// Enqueue enqueues ns/name of the given api object in the task queue. +func (t *Queue) Enqueue(obj interface{}) { + glog.V(3).Infof("queuing item %v", obj) + key, err := t.fn(obj) + if err != nil { + glog.Errorf("%v", err) + return + } + t.queue.Add(key) +} + +func (t *Queue) defaultKeyFunc(obj interface{}) (interface{}, error) { + key, err := keyFunc(obj) + if err != nil { + return "", fmt.Errorf("could not get key for object %+v: %v", obj, err) + } + + return key, nil +} + +// worker processes work in the queue through sync. +func (t *Queue) worker() { + for { + key, quit := t.queue.Get() + if quit { + close(t.workerDone) + return + } + glog.V(3).Infof("syncing %v", key) + if err := t.sync(key); err != nil { + glog.Warningf("requeuing %v, err %v", key, err) + t.queue.AddRateLimited(key) + } else { + t.queue.Forget(key) + } + + t.queue.Done(key) + } +} + +// Shutdown shuts down the work queue and waits for the worker to ACK +func (t *Queue) Shutdown() { + t.queue.ShutDown() + <-t.workerDone +} + +// IsShuttingDown returns if the method Shutdown was invoked +func (t *Queue) IsShuttingDown() bool { + return t.queue.ShuttingDown() +} + +// NewTaskQueue creates a new task queue with the given sync function. +// The sync function is called for every element inserted into the queue. +func NewTaskQueue(syncFn func(interface{}) error) *Queue { + return NewCustomTaskQueue(syncFn, nil) +} + +// NewCustomTaskQueue ... +func NewCustomTaskQueue(syncFn func(interface{}) error, fn func(interface{}) (interface{}, error)) *Queue { + q := &Queue{ + queue: workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter()), + sync: syncFn, + workerDone: make(chan struct{}), + fn: fn, + } + + if fn == nil { + q.fn = q.defaultKeyFunc + } + + return q +} diff --git a/controllers/nginx/nginx/template/file_watcher.go b/core/pkg/watch/file_watcher.go similarity index 78% rename from controllers/nginx/nginx/template/file_watcher.go rename to core/pkg/watch/file_watcher.go index 8a1d05bac9..fe85c4cd0d 100644 --- a/controllers/nginx/nginx/template/file_watcher.go +++ b/core/pkg/watch/file_watcher.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package template +package watch import ( "log" @@ -23,28 +23,31 @@ import ( "gopkg.in/fsnotify.v1" ) -type fileWatcher struct { +// FileWatcher defines a watch over a file +type FileWatcher struct { file string watcher *fsnotify.Watcher + // onEvent callback to be invoked after the file being watched changes onEvent func() } -func newFileWatcher(file string, onEvent func()) (fileWatcher, error) { - fw := fileWatcher{ +// NewFileWatcher creates a new FileWatcher +func NewFileWatcher(file string, onEvent func()) (FileWatcher, error) { + fw := FileWatcher{ file: file, onEvent: onEvent, } - err := fw.watch() return fw, err } -func (f fileWatcher) close() error { +// Close ends the watch +func (f FileWatcher) Close() error { return f.watcher.Close() } // watch creates a fsnotify watcher for a file and create of write events -func (f *fileWatcher) watch() error { +func (f *FileWatcher) watch() error { watcher, err := fsnotify.NewWatcher() if err != nil { return err diff --git a/core/pkg/watch/file_watcher_test.go b/core/pkg/watch/file_watcher_test.go new file mode 100644 index 0000000000..31833f74ff --- /dev/null +++ b/core/pkg/watch/file_watcher_test.go @@ -0,0 +1,45 @@ +/* +Copyright 2015 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 watch + +import ( + "io/ioutil" + "testing" +) + +func TestFileWatcher(t *testing.T) { + file, err := ioutil.TempFile("", "fw") + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + defer file.Close() + count := 0 + fw, err := NewFileWatcher(file.Name(), func() { + count++ + if count != 1 { + t.Fatalf("expected 1 but returned %v", count) + } + }) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + defer fw.Close() + if count != 0 { + t.Fatalf("expected 0 but returned %v", count) + } + ioutil.WriteFile(file.Name(), []byte{}, 0644) +} diff --git a/hack/e2e-internal/e2e-down.sh b/hack/e2e-internal/e2e-down.sh new file mode 100755 index 0000000000..62ee7aec29 --- /dev/null +++ b/hack/e2e-internal/e2e-down.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +[[ $DEBUG ]] && set -x + +set -eof pipefail + +# include env +. hack/e2e-internal/e2e-env.sh + +echo "Destroying running docker containers..." +# do not failt if the container is not running +docker rm -f kubelet || true +docker rm -f apiserver || true +docker rm -f etcd || true diff --git a/hack/e2e-internal/e2e-env.sh b/hack/e2e-internal/e2e-env.sh new file mode 100755 index 0000000000..d0747bb6e0 --- /dev/null +++ b/hack/e2e-internal/e2e-env.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +[[ $DEBUG ]] && set -x + +export ETCD_VERSION=3.0.14 +export K8S_VERSION=1.4.5 + +export PWD=`pwd` +export BASEDIR="$(dirname ${BASH_SOURCE})" +export KUBECTL="${BASEDIR}/kubectl" +export GOOS="${GOOS:-linux}" + +if [ ! -e ${KUBECTL} ]; then + echo "kubectl binary is missing. downloading..." + curl -sSL http://storage.googleapis.com/kubernetes-release/release/v${K8S_VERSION}/bin/${GOOS}/amd64/kubectl -o ${KUBECTL} + chmod u+x ${KUBECTL} +fi + +${KUBECTL} config set-cluster travis --server=http://0.0.0.0:8080 +${KUBECTL} config set-context travis --cluster=travis +${KUBECTL} config use-context travis diff --git a/hack/e2e-internal/e2e-status.sh b/hack/e2e-internal/e2e-status.sh new file mode 100755 index 0000000000..21a4e9b291 --- /dev/null +++ b/hack/e2e-internal/e2e-status.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +[[ $DEBUG ]] && set -x + +set -eof pipefail + +# include env +. hack/e2e-internal/e2e-env.sh + +echo "Kubernetes information:" +${KUBECTL} version diff --git a/hack/e2e-internal/e2e-up.sh b/hack/e2e-internal/e2e-up.sh new file mode 100755 index 0000000000..15b2d46312 --- /dev/null +++ b/hack/e2e-internal/e2e-up.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash + +[[ $DEBUG ]] && set -x + +set -eof pipefail + +# include env +. hack/e2e-internal/e2e-env.sh + +echo "Starting etcd..." +docker run -d \ + --net=host \ + --name=etcd \ + quay.io/coreos/etcd:v$ETCD_VERSION + +echo "Starting kubernetes..." + +docker run -d --name=apiserver \ + --net=host \ + --pid=host \ + --privileged=true \ + gcr.io/google_containers/hyperkube:v${K8S_VERSION} \ + /hyperkube apiserver \ + --insecure-bind-address=0.0.0.0 \ + --service-cluster-ip-range=10.0.0.1/24 \ + --etcd_servers=http://127.0.0.1:4001 \ + --v=2 + +docker run -d --name=kubelet \ + --volume=/:/rootfs:ro \ + --volume=/sys:/sys:ro \ + --volume=/dev:/dev \ + --volume=/var/lib/docker/:/var/lib/docker:rw \ + --volume=/var/lib/kubelet/:/var/lib/kubelet:rw \ + --volume=/var/run:/var/run:rw \ + --net=host \ + --pid=host \ + --privileged=true \ + gcr.io/google_containers/hyperkube:v${K8S_VERSION} \ + /hyperkube kubelet \ + --containerized \ + --hostname-override="0.0.0.0" \ + --address="0.0.0.0" \ + --cluster_dns=10.0.0.10 --cluster_domain=cluster.local \ + --api-servers=http://localhost:8080 \ + --config=/etc/kubernetes/manifests-multi + +echo "waiting until api server is available..." +until curl -o /dev/null -sIf http://0.0.0.0:8080; do \ + sleep 10; +done; + +echo "Kubernetes started" +echo "Kubernetes information:" +${KUBECTL} version diff --git a/hack/e2e-internal/ginkgo-e2e.sh b/hack/e2e-internal/ginkgo-e2e.sh new file mode 100755 index 0000000000..aa3c61ce6e --- /dev/null +++ b/hack/e2e-internal/ginkgo-e2e.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +echo "running ginkgo" \ No newline at end of file diff --git a/hack/e2e.go b/hack/e2e.go new file mode 100644 index 0000000000..d6ef3fa060 --- /dev/null +++ b/hack/e2e.go @@ -0,0 +1,285 @@ +/* +Copyright 2014 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. +*/ + +// e2e.go runs the e2e test suite. No non-standard package dependencies; call with "go run". +package main + +import ( + "encoding/xml" + "flag" + "fmt" + "io/ioutil" + "log" + "os" + "os/exec" + "path/filepath" + "strings" + "time" +) + +var ( + build = flag.Bool("build", true, "Build the backends images indicated by the env var BACKENDS required to run e2e tests.") + up = flag.Bool("up", true, "Creates a kubernetes cluster using hyperkube (containerized kubelet).") + down = flag.Bool("down", true, "destroys the created cluster.") + test = flag.Bool("test", true, "Run Ginkgo tests.") + dump = flag.String("dump", "", "If set, dump cluster logs to this location on test or cluster-up failure") + testArgs = flag.String("test-args", "", "Space-separated list of arguments to pass to Ginkgo test runner.") + deployment = flag.String("deployment", "bash", "up/down mechanism") + verbose = flag.Bool("v", false, "If true, print all command output.") +) + +func appendError(errs []error, err error) []error { + if err != nil { + return append(errs, err) + } + return errs +} + +func validWorkingDirectory() error { + cwd, err := os.Getwd() + if err != nil { + return fmt.Errorf("could not get pwd: %v", err) + } + acwd, err := filepath.Abs(cwd) + if err != nil { + return fmt.Errorf("failed to convert %s to an absolute path: %v", cwd, err) + } + if !strings.Contains(filepath.Base(acwd), "ingress-controller") { + return fmt.Errorf("must run from git root directory: %v", acwd) + } + return nil +} + +type TestCase struct { + XMLName xml.Name `xml:"testcase"` + ClassName string `xml:"classname,attr"` + Name string `xml:"name,attr"` + Time float64 `xml:"time,attr"` + Failure string `xml:"failure,omitempty"` +} + +type TestSuite struct { + XMLName xml.Name `xml:"testsuite"` + Failures int `xml:"failures,attr"` + Tests int `xml:"tests,attr"` + Time float64 `xml:"time,attr"` + Cases []TestCase +} + +var suite TestSuite + +func xmlWrap(name string, f func() error) error { + start := time.Now() + err := f() + duration := time.Since(start) + c := TestCase{ + Name: name, + ClassName: "e2e.go", + Time: duration.Seconds(), + } + if err != nil { + c.Failure = err.Error() + suite.Failures++ + } + suite.Cases = append(suite.Cases, c) + suite.Tests++ + return err +} + +func writeXML(start time.Time) { + suite.Time = time.Since(start).Seconds() + out, err := xml.MarshalIndent(&suite, "", " ") + if err != nil { + log.Fatalf("Could not marshal XML: %s", err) + } + path := filepath.Join(*dump, "junit_runner.xml") + f, err := os.Create(path) + if err != nil { + log.Fatalf("Could not create file: %s", err) + } + defer f.Close() + if _, err := f.WriteString(xml.Header); err != nil { + log.Fatalf("Error writing XML header: %s", err) + } + if _, err := f.Write(out); err != nil { + log.Fatalf("Error writing XML data: %s", err) + } + log.Printf("Saved XML output to %s.", path) +} + +func main() { + log.SetFlags(log.LstdFlags | log.Lshortfile) + flag.Parse() + + if err := validWorkingDirectory(); err != nil { + log.Fatalf("Called from invalid working directory: %v", err) + } + + deploy, err := getDeployer() + if err != nil { + log.Fatalf("Error creating deployer: %v", err) + } + + if err := run(deploy); err != nil { + log.Fatalf("Something went wrong: %s", err) + } +} + +func run(deploy deployer) error { + if *dump != "" { + defer writeXML(time.Now()) + } + + if *build { + if err := xmlWrap("Build", Build); err != nil { + return fmt.Errorf("error building: %s", err) + } + } + + if *up { + if err := xmlWrap("TearDown", deploy.Down); err != nil { + return fmt.Errorf("error tearing down previous cluster: %s", err) + } + } + + var errs []error + + if *up { + // If we tried to bring the cluster up, make a courtesy + // attempt to bring it down so we're not leaving resources around. + // + // TODO: We should try calling deploy.Down exactly once. Though to + // stop the leaking resources for now, we want to be on the safe side + // and call it explictly in defer if the other one is not called. + if *down { + defer xmlWrap("Deferred TearDown", deploy.Down) + } + // Start the cluster using this version. + if err := xmlWrap("Up", deploy.Up); err != nil { + return fmt.Errorf("starting e2e cluster: %s", err) + } + if *dump != "" { + cmd := exec.Command("./cluster/kubectl.sh", "--match-server-version=false", "get", "nodes", "-oyaml") + b, err := cmd.CombinedOutput() + if *verbose { + log.Printf("kubectl get nodes:\n%s", string(b)) + } + if err == nil { + if err := ioutil.WriteFile(filepath.Join(*dump, "nodes.yaml"), b, 0644); err != nil { + errs = appendError(errs, fmt.Errorf("error writing nodes.yaml: %v", err)) + } + } else { + errs = appendError(errs, fmt.Errorf("error running get nodes: %v", err)) + } + } + } + + if *test { + if err := xmlWrap("IsUp", deploy.IsUp); err != nil { + errs = appendError(errs, err) + } else { + errs = appendError(errs, Test()) + } + } + + if len(errs) > 0 && *dump != "" { + errs = appendError(errs, xmlWrap("DumpClusterLogs", func() error { + return DumpClusterLogs(*dump) + })) + } + + if *down { + errs = appendError(errs, xmlWrap("TearDown", deploy.Down)) + } + + if len(errs) != 0 { + return fmt.Errorf("encountered %d errors: %v", len(errs), errs) + } + return nil +} + +func Build() error { + // The build-release script needs stdin to ask the user whether + // it's OK to download the docker image. + cmd := exec.Command("make", "backends", "backends-images", "backends-push") + cmd.Stdin = os.Stdin + if err := finishRunning("build-release", cmd); err != nil { + return fmt.Errorf("error building: %v", err) + } + return nil +} + +type deployer interface { + Up() error + IsUp() error + SetupKubecfg() error + Down() error +} + +func getDeployer() (deployer, error) { + switch *deployment { + case "bash": + return bash{}, nil + default: + return nil, fmt.Errorf("Unknown deployment strategy %q", *deployment) + } +} + +type bash struct{} + +func (b bash) Up() error { + return finishRunning("up", exec.Command("./hack/e2e-internal/e2e-up.sh")) +} + +func (b bash) IsUp() error { + return finishRunning("get status", exec.Command("./hack/e2e-internal/e2e-status.sh")) +} + +func (b bash) SetupKubecfg() error { + return nil +} + +func (b bash) Down() error { + return finishRunning("teardown", exec.Command("./hack/e2e-internal/e2e-down.sh")) +} + +func DumpClusterLogs(location string) error { + log.Printf("Dumping cluster logs to: %v", location) + return finishRunning("dump cluster logs", exec.Command("./hack/e2e-internal/log-dump.sh", location)) +} + +func Test() error { + if *testArgs == "" { + *testArgs = "--ginkgo.focus=\\[Feature:Ingress\\]" + } + return finishRunning("Ginkgo tests", exec.Command("./hack/e2e-internal/ginkgo-e2e.sh", strings.Fields(*testArgs)...)) +} + +func finishRunning(stepName string, cmd *exec.Cmd) error { + if *verbose { + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + } + log.Printf("Running: %v", stepName) + defer func(start time.Time) { + log.Printf("Step '%s' finished in %s", stepName, time.Since(start)) + }(time.Now()) + + if err := cmd.Run(); err != nil { + return fmt.Errorf("error running %v: %v", stepName, err) + } + return nil +} From f2b627486d7f95b88fa9ff5f4515163cf3c69f0f Mon Sep 17 00:00:00 2001 From: Manuel de Brito Fontes Date: Fri, 11 Nov 2016 20:43:35 -0300 Subject: [PATCH 2/5] Remove interface --- controllers/nginx/README.md | 468 ------------------ controllers/nginx/configuration.md | 4 +- controllers/nginx/pkg/cmd/controller/main.go | 2 +- controllers/nginx/pkg/cmd/controller/nginx.go | 4 +- controllers/nginx/pkg/template/template.go | 6 +- .../nginx/pkg/template/template_test.go | 2 +- controllers/nginx/rc.yaml | 107 ---- .../rootfs/etc/nginx/template/nginx.tmpl | 10 +- core/pkg/ingress/controller/backend_ssl.go | 10 +- core/pkg/ingress/controller/controller.go | 95 ++-- core/pkg/ingress/controller/launch.go | 10 +- core/pkg/ingress/controller/util.go | 12 +- core/pkg/ingress/types.go | 214 -------- 13 files changed, 72 insertions(+), 872 deletions(-) delete mode 100644 controllers/nginx/rc.yaml delete mode 100644 core/pkg/ingress/types.go diff --git a/controllers/nginx/README.md b/controllers/nginx/README.md index 5af7c5e324..43127725d8 100644 --- a/controllers/nginx/README.md +++ b/controllers/nginx/README.md @@ -1,470 +1,2 @@ -[![Build Status](https://travis-ci.org/aledbf/ingress-controller.svg?branch=master)](https://travis-ci.org/aledbf/ingress-controller) -[![Coverage Status](https://coveralls.io/repos/github/aledbf/ingress-controller/badge.svg?branch=master)](https://coveralls.io/github/aledbf/ingress-controller?branch=master) -[![Go Report Card](https://goreportcard.com/badge/github.com/aledbf/ingress-controller)](https://goreportcard.com/report/github.com/aledbf/ingress-controller) - # Nginx Ingress Controller - -This is an nginx Ingress controller that uses [ConfigMap](https://github.com/kubernetes/kubernetes/blob/master/docs/design/configmap.md) to store the nginx configuration. See [Ingress controller documentation](../README.md) for details on how it works. - -## Contents -* [Recent changes](#recent-changes) -* [Conventions](#conventions) -* [Requirements](#what-it-provides) -* [Deployment](#deployment) -* [Health checks](#health-checks) -* [HTTP](#http) -* [HTTPS](#https) - * [Default SSL Certificate](#default-ssl-certificate) - * [HTTPS enforcement](#server-side-https-enforcement) - * [HSTS](#http-strict-transport-security) - * [Kube-Lego](#automated-certificate-management-with-kube-lego) -* [TCP Services](#exposing-tcp-services) -* [UDP Services](#exposing-udp-services) -* [Proxy Protocol](#proxy-protocol) -* [Service Integration](#service-integration) -* [NGINX customization](configuration.md) -* [NGINX status page](#nginx-status-page) -* [Running multiple ingress controllers](#running-multiple-ingress-controllers) -* [Running on Cloudproviders](#running-on-cloudproviders) -* [Disabling NGINX ingress controller](#disabling-nginx-ingress-controller) -* [Log format](#log-format) -* [Local cluster](#local-cluster) -* [Debug & Troubleshooting](#troubleshooting) -* [Why endpoints and not services?](#why-endpoints-and-not-services) -* [Metrics](#metrics) -* [Limitations](#limitations) -* [NGINX Notes](#nginx-notes) - -## Recent changes - -Change history is available in [CHANGELOG.md](CHANGELOG.md) - - -## Conventions - -Anytime we reference a tls secret, we mean (x509, pem encoded, RSA 2048, etc). You can generate such a certificate with: -`openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout $(KEY) -out $(CERT) -subj "/CN=$(HOST)/O=$(HOST)"` -and create the secret via `kubectl create secret tls --key file --cert file` - - -## Requirements -- Default backend [404-server](https://github.com/kubernetes/contrib/tree/master/404-server) - - -## Deployment - -First create a default backend: -``` -$ kubectl create -f examples/default-backend.yaml -$ kubectl expose rc default-http-backend --port=80 --target-port=8080 --name=default-http-backend -``` - -Loadbalancers are created via a ReplicationController or Daemonset: - -``` -$ kubectl create -f examples/default/rc-default.yaml -``` - -## Health checks - -The proveded examples in the Ingress controller use a `readiness` and `liveness` probe. By default the URL is `/healthz` and the port `18080`. -Using the flag `--health-check-path` is possible to specify a custom path. -In some environments only port 80 is allowed to enable health checks. For this reason the Ingress controller exposes this path in the default server. - -If PROXY protocol is enabled the health check must use the default port `18080`. This is required because Kubernetes probes do not understand PROXY protocol. - - -## HTTP - -First we need to deploy some application to publish. To keep this simple we will use the [echoheaders app](https://github.com/kubernetes/contrib/blob/master/ingress/echoheaders/echo-app.yaml) that just returns information about the http request as output -``` -kubectl run echoheaders --image=gcr.io/google_containers/echoserver:1.4 --replicas=1 --port=8080 -``` - -Now we expose the same application in two different services (so we can create different Ingress rules) -``` -kubectl expose deployment echoheaders --port=80 --target-port=8080 --name=echoheaders-x -kubectl expose deployment echoheaders --port=80 --target-port=8080 --name=echoheaders-y -``` - -Next we create a couple of Ingress rules -``` -kubectl create -f examples/ingress.yaml -``` - -we check that ingress rules are defined: -``` -$ kubectl get ing -NAME RULE BACKEND ADDRESS -echomap - - foo.bar.com - /foo echoheaders-x:80 - bar.baz.com - /bar echoheaders-y:80 - /foo echoheaders-x:80 -``` - -Before the deploy of the Ingress controller we need a default backend [404-server](https://github.com/kubernetes/contrib/tree/master/404-server) -``` -kubectl create -f examples/default-backend.yaml -kubectl expose rc default-http-backend --port=80 --target-port=8080 --name=default-http-backend -``` - -Check NGINX it is running with the defined Ingress rules: - -``` -$ LBIP=$(kubectl get node `kubectl get po -l name=nginx-ingress-lb --template '{{range .items}}{{.spec.nodeName}}{{end}}'` --template '{{range $i, $n := .status.addresses}}{{if eq $n.type "ExternalIP"}}{{$n.address}}{{end}}{{end}}') -$ curl $LBIP/foo -H 'Host: foo.bar.com' -``` - -## HTTPS - -You can secure an Ingress by specifying a secret that contains a TLS private key and certificate. Currently the Ingress only supports a single TLS port, 443, and assumes TLS termination. This controller supports SNI. The TLS secret must contain keys named tls.crt and tls.key that contain the certificate and private key to use for TLS, eg: - -``` -apiVersion: v1 -data: - tls.crt: base64 encoded cert - tls.key: base64 encoded key -kind: Secret -metadata: - name: testsecret - namespace: default -type: Opaque -``` - -Referencing this secret in an Ingress will tell the Ingress controller to secure the channel from the client to the loadbalancer using TLS: - -``` -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: no-rules-map -spec: - tls: - secretName: testsecret - backend: - serviceName: s1 - servicePort: 80 -``` -Please follow [test.sh](https://github.com/bprashanth/Ingress/blob/master/examples/sni/nginx/test.sh) as a guide on how to generate secrets containing SSL certificates. The name of the secret can be different than the name of the certificate. - -Check the [example](examples/tls/README.md) - - -### Default SSL Certificate - -NGINX provides the option [server name](http://nginx.org/en/docs/http/server_names.html) as a catch-all in case of requests that do not match one of the configured server names. This configuration works without issues for HTTP traffic. In case of HTTPS NGINX requires a certificate. For this reason the Ingress controller provides the flag `--default-ssl-certificate`. The secret behind this flag contains the default certificate to be used in the mentioned case. -If this flag is not provided NGINX will use a self signed certificate. - -Running without the flag `--default-ssl-certificate`: - -``` -$ curl -v https://10.2.78.7:443 -k -* Rebuilt URL to: https://10.2.78.7:443/ -* Trying 10.2.78.4... -* Connected to 10.2.78.7 (10.2.78.7) port 443 (#0) -* ALPN, offering http/1.1 -* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH -* successfully set certificate verify locations: -* CAfile: /etc/ssl/certs/ca-certificates.crt - CApath: /etc/ssl/certs -* TLSv1.2 (OUT), TLS header, Certificate Status (22): -* TLSv1.2 (OUT), TLS handshake, Client hello (1): -* TLSv1.2 (IN), TLS handshake, Server hello (2): -* TLSv1.2 (IN), TLS handshake, Certificate (11): -* TLSv1.2 (IN), TLS handshake, Server key exchange (12): -* TLSv1.2 (IN), TLS handshake, Server finished (14): -* TLSv1.2 (OUT), TLS handshake, Client key exchange (16): -* TLSv1.2 (OUT), TLS change cipher, Client hello (1): -* TLSv1.2 (OUT), TLS handshake, Finished (20): -* TLSv1.2 (IN), TLS change cipher, Client hello (1): -* TLSv1.2 (IN), TLS handshake, Finished (20): -* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256 -* ALPN, server accepted to use http/1.1 -* Server certificate: -* subject: CN=foo.bar.com -* start date: Apr 13 00:50:56 2016 GMT -* expire date: Apr 13 00:50:56 2017 GMT -* issuer: CN=foo.bar.com -* SSL certificate verify result: self signed certificate (18), continuing anyway. -> GET / HTTP/1.1 -> Host: 10.2.78.7 -> User-Agent: curl/7.47.1 -> Accept: */* -> -< HTTP/1.1 404 Not Found -< Server: nginx/1.11.1 -< Date: Thu, 21 Jul 2016 15:38:46 GMT -< Content-Type: text/html -< Transfer-Encoding: chunked -< Connection: keep-alive -< Strict-Transport-Security: max-age=15724800; includeSubDomains; preload -< -The page you're looking for could not be found. - -* Connection #0 to host 10.2.78.7 left intact -``` - -Specifying `--default-ssl-certificate=default/foo-tls`: - -``` -core@localhost ~ $ curl -v https://10.2.78.7:443 -k -* Rebuilt URL to: https://10.2.78.7:443/ -* Trying 10.2.78.7... -* Connected to 10.2.78.7 (10.2.78.7) port 443 (#0) -* ALPN, offering http/1.1 -* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH -* successfully set certificate verify locations: -* CAfile: /etc/ssl/certs/ca-certificates.crt - CApath: /etc/ssl/certs -* TLSv1.2 (OUT), TLS header, Certificate Status (22): -* TLSv1.2 (OUT), TLS handshake, Client hello (1): -* TLSv1.2 (IN), TLS handshake, Server hello (2): -* TLSv1.2 (IN), TLS handshake, Certificate (11): -* TLSv1.2 (IN), TLS handshake, Server key exchange (12): -* TLSv1.2 (IN), TLS handshake, Server finished (14): -* TLSv1.2 (OUT), TLS handshake, Client key exchange (16): -* TLSv1.2 (OUT), TLS change cipher, Client hello (1): -* TLSv1.2 (OUT), TLS handshake, Finished (20): -* TLSv1.2 (IN), TLS change cipher, Client hello (1): -* TLSv1.2 (IN), TLS handshake, Finished (20): -* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256 -* ALPN, server accepted to use http/1.1 -* Server certificate: -* subject: CN=foo.bar.com -* start date: Apr 13 00:50:56 2016 GMT -* expire date: Apr 13 00:50:56 2017 GMT -* issuer: CN=foo.bar.com -* SSL certificate verify result: self signed certificate (18), continuing anyway. -> GET / HTTP/1.1 -> Host: 10.2.78.7 -> User-Agent: curl/7.47.1 -> Accept: */* -> -< HTTP/1.1 404 Not Found -< Server: nginx/1.11.1 -< Date: Mon, 18 Jul 2016 21:02:59 GMT -< Content-Type: text/html -< Transfer-Encoding: chunked -< Connection: keep-alive -< Strict-Transport-Security: max-age=15724800; includeSubDomains; preload -< -The page you're looking for could not be found. - -* Connection #0 to host 10.2.78.7 left intact -``` - - -### Server-side HTTPS enforcement - -By default the controller redirects (301) to HTTPS if TLS is enabled for that ingress . If you want to disable that behaviour globally, you can use `ssl-redirect: "false"` in the NGINX config map. - -To configure this feature for specific ingress resources, you can use the `ingress.kubernetes.io/ssl-redirect: "false"` annotation in the particular resource. - - -### HTTP Strict Transport Security - -HTTP Strict Transport Security (HSTS) is an opt-in security enhancement specified through the use of a special response header. Once a supported browser receives this header that browser will prevent any communications from being sent over HTTP to the specified domain and will instead send all communications over HTTPS. - -By default the controller redirects (301) to HTTPS if there is a TLS Ingress rule. - -To disable this behavior use `hsts=false` in the NGINX config map. - - -### Automated Certificate Management with Kube-Lego - -[Kube-Lego] automatically requests missing certificates or expired from -[Let's Encrypt] by monitoring ingress resources and its referenced secrets. To -enable this for an ingress resource you have to add an annotation: - -``` -kubectl annotate ing ingress-demo kubernetes.io/tls-acme="true" -``` - -To setup Kube-Lego you can take a look at this [full example]. The first -version to fully support Kube-Lego is nginx Ingress controller 0.8. - -[full example]:https://github.com/jetstack/kube-lego/tree/master/examples -[Kube-Lego]:https://github.com/jetstack/kube-lego -[Let's Encrypt]:https://letsencrypt.org - -## Exposing TCP services - -Ingress does not support TCP services (yet). For this reason this Ingress controller uses the flag `--tcp-services-configmap` to point to an existing config map where the key is the external port to use and the value is `:` -It is possible to use a number or the name of the port. - -The next example shows how to expose the service `example-go` running in the namespace `default` in the port `8080` using the port `9000` -``` -apiVersion: v1 -kind: ConfigMap -metadata: - name: tcp-configmap-example -data: - 9000: "default/example-go:8080" -``` - - -Please check the [tcp services](examples/tcp/README.md) example - -## Exposing UDP services - -Since 1.9.13 NGINX provides [UDP Load Balancing](https://www.nginx.com/blog/announcing-udp-load-balancing/). - -Ingress does not support UDP services (yet). For this reason this Ingress controller uses the flag `--udp-services-configmap` to point to an existing config map where the key is the external port to use and the value is `:` -It is possible to use a number or the name of the port. - -The next example shows how to expose the service `kube-dns` running in the namespace `kube-system` in the port `53` using the port `53` -``` -apiVersion: v1 -kind: ConfigMap -metadata: - name: udp-configmap-example -data: - 53: "kube-system/kube-dns:53" -``` - - -Please check the [udp services](examples/udp/README.md) example - -## Proxy Protocol - -If you are using a L4 proxy to forward the traffic to the NGINX pods and terminate HTTP/HTTPS there, you will lose the remote endpoint's IP addresses. To prevent this you could use the [Proxy Protocol](http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt) for forwarding traffic, this will send the connection details before forwarding the actual TCP connection itself. - -Amongst others [ELBs in AWS](http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/enable-proxy-protocol.html) and [HAProxy](http://www.haproxy.org/) support Proxy Protocol. - -Please check the [proxy-protocol](examples/proxy-protocol/) example - - -## Service Integration - -On clouds like AWS or GCE, using a service with `Type=LoadBalancer` allows the default kubernetes integration, which can save a lot of work. -By passing the `--publish-service` argument to the controller, the ingress status will be updated with the load balancer configuration of the service, rather than the IP/s of the node/s. - - -### Custom errors - -In case of an error in a request the body of the response is obtained from the `default backend`. Each request to the default backend includes two headers: -- `X-Code` indicates the HTTP code -- `X-Format` the value of the `Accept` header - -Using this two headers is possible to use a custom backend service like [this one](https://github.com/aledbf/contrib/tree/nginx-debug-server/Ingress/images/nginx-error-server) that inspect each request and returns a custom error page with the format expected by the client. Please check the example [custom-errors](examples/custom-errors/README.md) - -### NGINX status page - -The ngx_http_stub_status_module module provides access to basic status information. This is the default module active in the url `/nginx_status`. -This controller provides an alternative to this module using [nginx-module-vts](https://github.com/vozlt/nginx-module-vts) third party module. -To use this module just provide a config map with the key `enable-vts-status=true`. The URL is exposed in the port 8080. -Please check the example `example/rc-default.yaml` - -![nginx-module-vts screenshot](https://cloud.githubusercontent.com/assets/3648408/10876811/77a67b70-8183-11e5-9924-6a6d0c5dc73a.png "screenshot with filter") - -To extract the information in JSON format the module provides a custom URL: `/nginx_status/format/json` - -### Running multiple ingress controllers - -If you're running multiple ingress controllers, or running on a cloudprovider that natively handles -ingress, you need to specify the annotation `kubernetes.io/ingress.class: "nginx"` in all ingresses -that you would like this controller to claim. Not specifying the annotation will lead to multiple -ingress controllers claiming the same ingress. Specifying the wrong value will result in all ingress -controllers ignoring the ingress. Multiple ingress controllers running in the same cluster was not -supported in Kubernetes versions < 1.3. - -### Running on Cloudproviders - -If you're running this ingress controller on a cloudprovider, you should assume the provider also has a native -Ingress controller and specify the ingress.class annotation as indicated in this section. -In addition to this, you will need to add a firewall rule for each port this controller is listening on, i.e :80 and :443. - -### Disabling NGINX ingress controller - -Setting the annotation `kubernetes.io/ingress.class` to any value other than "nginx" or the empty string, will force the NGINX Ingress controller to ignore your Ingress. Do this if you wish to use one of the other Ingress controllers at the same time as the NGINX controller. - -### Log format - -The default configuration uses a custom logging format to add additional information about upstreams - -``` - log_format upstreaminfo '{{ if $cfg.useProxyProtocol }}$proxy_protocol_addr{{ else }}$remote_addr{{ end }} - ' - '[$proxy_add_x_forwarded_for] - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" ' - '$request_length $request_time [$proxy_upstream_name] $upstream_addr $upstream_response_length $upstream_response_time $upstream_status'; -``` - -Sources: - - [upstream variables](http://nginx.org/en/docs/http/ngx_http_upstream_module.html#variables) - - [embedded variables](http://nginx.org/en/docs/http/ngx_http_core_module.html#variables) - -Description: -- `$proxy_protocol_addr`: if PROXY protocol is enabled -- `$remote_addr`: if PROXY protocol is disabled (default) -- `$proxy_add_x_forwarded_for`: the `X-Forwarded-For` client request header field with the $remote_addr variable appended to it, separated by a comma -- `$remote_user`: user name supplied with the Basic authentication -- `$time_local`: local time in the Common Log Format -- `$request`: full original request line -- `$status`: response status -- `$body_bytes_sent`: number of bytes sent to a client, not counting the response header -- `$http_referer`: value of the Referer header -- `$http_user_agent`: value of User-Agent header -- `$request_length`: request length (including request line, header, and request body) -- `$request_time`: time elapsed since the first bytes were read from the client -- `$proxy_upstream_name`: name of the upstream. The format is `upstream---` -- `$upstream_addr`: keeps the IP address and port, or the path to the UNIX-domain socket of the upstream server. If several servers were contacted during request processing, their addresses are separated by commas -- `$upstream_response_length`: keeps the length of the response obtained from the upstream server -- `$upstream_response_time`: keeps time spent on receiving the response from the upstream server; the time is kept in seconds with millisecond resolution -- `$upstream_status`: keeps status code of the response obtained from the upstream server - -### Local cluster - -Using [`hack/local-up-cluster.sh`](https://github.com/kubernetes/kubernetes/blob/master/hack/local-up-cluster.sh) is possible to start a local kubernetes cluster consisting of a master and a single node. Please read [running-locally.md](https://github.com/kubernetes/kubernetes/blob/master/docs/devel/running-locally.md) for more details. - -Use of `hostNetwork: true` in the ingress controller is required to falls back at localhost:8080 for the apiserver if every other client creation check fails (eg: service account not present, kubeconfig doesn't exist, no master env vars...) - - -### Debug & Troubleshooting - -Using the flag `--v=XX` it is possible to increase the level of logging. -In particular: -- `--v=2` shows details using `diff` about the changes in the configuration in nginx - -``` -I0316 12:24:37.581267 1 utils.go:148] NGINX configuration diff a//etc/nginx/nginx.conf b//etc/nginx/nginx.conf -I0316 12:24:37.581356 1 utils.go:149] --- /tmp/922554809 2016-03-16 12:24:37.000000000 +0000 -+++ /tmp/079811012 2016-03-16 12:24:37.000000000 +0000 -@@ -235,7 +235,6 @@ - - upstream default-echoheadersx { - least_conn; -- server 10.2.112.124:5000; - server 10.2.208.50:5000; - - } -I0316 12:24:37.610073 1 command.go:69] change in configuration detected. Reloading... -``` - -- `--v=3` shows details about the service, Ingress rule, endpoint changes and it dumps the nginx configuration in JSON format -- `--v=5` configures NGINX in [debug mode](http://nginx.org/en/docs/debugging_log.html) - -### Metrics - -Using the doc [Instrumenting Kubernetes with a new metric](https://github.com/kubernetes/kubernetes/blob/master/docs/devel/instrumentation.md#instrumenting-kubernetes-with-a-new-metric) the Ingress controller -exposes the registered metrics via HTTP. Besides the default metrics provided by Prometheus is possible to get the number of reloads `reload_operations` and reloads with error `reload_operations_errors`, -ie error in validation in the configuration file before the reload. The metrics are exposed in port `10254` and path `/metrics`. -Using curl: `curl -v :10254/metrics` - - -### Limitations - -- Ingress rules for TLS require the definition of the field `host` - - -### Why endpoints and not services - -The NGINX ingress controller does not uses [Services](http://kubernetes.io/docs/user-guide/services) to route traffic to the pods. Instead it uses the Endpoints API in order to bypass [kube-proxy](http://kubernetes.io/docs/admin/kube-proxy/) to allow NGINX features like session affinity and custom load balancing algorithms. It also removes some overhead, such as conntrack entries for iptables DNAT. - - -### NGINX notes - -Since `gcr.io/google_containers/nginx-slim:0.8` NGINX contains the next patches: -- Dynamic TLS record size [nginx__dynamic_tls_records.patch](https://blog.cloudflare.com/optimizing-tls-over-tcp-to-reduce-latency/) -NGINX provides the parameter `ssl_buffer_size` to adjust the size of the buffer. Default value in NGINX is 16KB. The ingress controller changes the default to 4KB. This improves the [TLS Time To First Byte (TTTFB)](https://www.igvita.com/2013/12/16/optimizing-nginx-tls-time-to-first-byte/) but the size is fixed. This patches adapts the size of the buffer to the content is being served helping to improve the perceived latency. diff --git a/controllers/nginx/configuration.md b/controllers/nginx/configuration.md index b361fc459b..8a65d1949a 100644 --- a/controllers/nginx/configuration.md +++ b/controllers/nginx/configuration.md @@ -21,8 +21,8 @@ there are 3 ways to customize nginx 1. config map: create a stand alone config map, use this if you want a different global configuration -2. annoations: [annotate the ingress](#annotations), use this if you want a specific configuration for the site defined in the ingress rule -3. custom template: when is required a specific setting like [open_file_cache](http://nginx.org/en/docs/http/ngx_http_core_module.html#open_file_cache), custom [log_format](http://nginx.org/en/docs/http/ngx_http_log_module.html#log_format), adjust [listen](http://nginx.org/en/docs/http/ngx_http_core_module.html#listen) options as `rcvbuf` or when is not possible to change an through the config map +2. annotations: [annotate the ingress](#annotations), use this if you want a specific configuration for the site defined in the Ingress rule +3. custom template: when more specific settings are required, like [open_file_cache](http://nginx.org/en/docs/http/ngx_http_core_module.html#open_file_cache), custom [log_format](http://nginx.org/en/docs/http/ngx_http_log_module.html#log_format), adjust [listen](http://nginx.org/en/docs/http/ngx_http_core_module.html#listen) options as `rcvbuf` or when is not possible to change an through the config map #### Custom NGINX configuration diff --git a/controllers/nginx/pkg/cmd/controller/main.go b/controllers/nginx/pkg/cmd/controller/main.go index 4d7fc57566..c35d808a7c 100644 --- a/controllers/nginx/pkg/cmd/controller/main.go +++ b/controllers/nginx/pkg/cmd/controller/main.go @@ -43,7 +43,7 @@ func main() { } } -func handleSigterm(ic controller.Interface) { +func handleSigterm(ic *controller.GenericController) { signalChan := make(chan os.Signal, 1) signal.Notify(signalChan, syscall.SIGTERM) <-signalChan diff --git a/controllers/nginx/pkg/cmd/controller/nginx.go b/controllers/nginx/pkg/cmd/controller/nginx.go index a42360b83e..eb077a74e1 100644 --- a/controllers/nginx/pkg/cmd/controller/nginx.go +++ b/controllers/nginx/pkg/cmd/controller/nginx.go @@ -240,8 +240,8 @@ func (n NGINXController) OnUpdate(cmap *api.ConfigMap, ingressCfg ingress.Config conf["upstreams"] = ingressCfg.Upstreams conf["passthroughUpstreams"] = ingressCfg.PassthroughUpstreams conf["servers"] = ingressCfg.Servers - conf["tcpUpstreams"] = ingressCfg.TCPUpstreams - conf["udpUpstreams"] = ingressCfg.UDPUpstreams + conf["tcpUpstreams"] = ingressCfg.TCPEndpoints + conf["udpUpstreams"] = ingressCfg.UPDEndpoints conf["healthzURL"] = ingressCfg.HealthzURL conf["defResolver"] = cfg.Resolver conf["sslDHParam"] = "" diff --git a/controllers/nginx/pkg/template/template.go b/controllers/nginx/pkg/template/template.go index fcdef3af1c..7485b69628 100644 --- a/controllers/nginx/pkg/template/template.go +++ b/controllers/nginx/pkg/template/template.go @@ -197,7 +197,7 @@ func buildProxyPass(input interface{}) string { proto = "https" } // defProxyPass returns the default proxy_pass, just the name of the upstream - defProxyPass := fmt.Sprintf("proxy_pass %s://%s;", proto, location.Upstream.Name) + defProxyPass := fmt.Sprintf("proxy_pass %s://%s;", proto, location.Backend.Name) // if the path in the ingress rule is equals to the target: no special rewrite if path == location.Redirect.Target { return defProxyPass @@ -227,13 +227,13 @@ func buildProxyPass(input interface{}) string { rewrite %s(.*) /$1 break; rewrite %s / break; proxy_pass %s://%s; - %v`, path, location.Path, proto, location.Upstream.Name, abu) + %v`, path, location.Path, proto, location.Backend.Name, abu) } return fmt.Sprintf(` rewrite %s(.*) %s/$1 break; proxy_pass %s://%s; - %v`, path, location.Redirect.Target, proto, location.Upstream.Name, abu) + %v`, path, location.Redirect.Target, proto, location.Backend.Name, abu) } // default proxy_pass diff --git a/controllers/nginx/pkg/template/template_test.go b/controllers/nginx/pkg/template/template_test.go index 00d531c324..4dbb73e4cc 100644 --- a/controllers/nginx/pkg/template/template_test.go +++ b/controllers/nginx/pkg/template/template_test.go @@ -88,7 +88,7 @@ func TestBuildProxyPass(t *testing.T) { loc := &ingress.Location{ Path: tc.Path, Redirect: rewrite.Redirect{Target: tc.Target, AddBaseURL: tc.AddBaseURL}, - Upstream: ingress.Upstream{Name: "upstream-name"}, + Upstream: ingress.Backend{Name: "upstream-name"}, } pp := buildProxyPass(loc) diff --git a/controllers/nginx/rc.yaml b/controllers/nginx/rc.yaml deleted file mode 100644 index 9b299b9272..0000000000 --- a/controllers/nginx/rc.yaml +++ /dev/null @@ -1,107 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: default-http-backend - labels: - k8s-app: default-http-backend -spec: - ports: - - port: 80 - targetPort: 8080 - protocol: TCP - name: http - selector: - k8s-app: default-http-backend ---- -apiVersion: v1 -kind: ReplicationController -metadata: - name: default-http-backend -spec: - replicas: 1 - selector: - k8s-app: default-http-backend - template: - metadata: - labels: - k8s-app: default-http-backend - spec: - terminationGracePeriodSeconds: 60 - containers: - - name: default-http-backend - # Any image is permissable as long as: - # 1. It serves a 404 page at / - # 2. It serves 200 on a /healthz endpoint - image: gcr.io/google_containers/defaultbackend:1.0 - livenessProbe: - httpGet: - path: /healthz - port: 8080 - scheme: HTTP - initialDelaySeconds: 30 - timeoutSeconds: 5 - ports: - - containerPort: 8080 - resources: - limits: - cpu: 10m - memory: 20Mi - requests: - cpu: 10m - memory: 20Mi ---- -apiVersion: v1 -kind: ReplicationController -metadata: - name: nginx-ingress-controller - labels: - k8s-app: nginx-ingress-lb -spec: - replicas: 1 - selector: - k8s-app: nginx-ingress-lb - template: - metadata: - labels: - k8s-app: nginx-ingress-lb - name: nginx-ingress-lb - spec: - terminationGracePeriodSeconds: 60 - containers: - - image: gcr.io/google_containers/nginx-ingress-controller:0.8.3 - name: nginx-ingress-lb - imagePullPolicy: Always - readinessProbe: - httpGet: - path: /healthz - port: 10254 - scheme: HTTP - livenessProbe: - httpGet: - path: /healthz - port: 10254 - scheme: HTTP - initialDelaySeconds: 10 - timeoutSeconds: 1 - # use downward API - env: - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - ports: - - containerPort: 80 - hostPort: 80 - - containerPort: 443 - hostPort: 443 - # we expose 18080 to access nginx stats in url /nginx-status - # this is optional - - containerPort: 18080 - hostPort: 18080 - args: - - /nginx-ingress-controller - - --default-backend-service=$(POD_NAMESPACE)/default-http-backend diff --git a/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl b/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl index 18afc359d3..b2330acd39 100644 --- a/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl +++ b/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl @@ -173,7 +173,7 @@ http { {{ else }} least_conn; {{ end }} - {{ range $server := $upstream.Backends }}server {{ $server.Address }}:{{ $server.Port }} max_fails={{ $server.MaxFails }} fail_timeout={{ $server.FailTimeout }}; + {{ range $server := $upstream.Endpoints }}server {{ $server.Address }}:{{ $server.Port }} max_fails={{ $server.MaxFails }} fail_timeout={{ $server.FailTimeout }}; {{ end }} } {{ end }} @@ -300,7 +300,7 @@ http { proxy_set_header Accept-Encoding ""; {{ end }} - set $proxy_upstream_name "{{ $location.Upstream.Name }}"; + set $proxy_upstream_name "{{ $location.Backend.Name }}"; {{ buildProxyPass $location }} } {{ end }} @@ -396,7 +396,7 @@ stream { {{ range $i, $passthrough := .passthroughUpstreams }} upstream {{ $passthrough.Name }}-{{ $i }}-pt { - {{ range $server := $passthrough.Backends }}server {{ $server.Address }}:{{ $server.Port }}; + {{ range $server := $passthrough.Endpoints }}server {{ $server.Address }}:{{ $server.Port }}; {{ end }} } {{ end }} @@ -413,7 +413,7 @@ stream { # TCP services {{ range $i, $tcpServer := .tcpUpstreams }} upstream tcp-{{ $tcpServer.Upstream.Name }} { - {{ range $server := $tcpServer.Upstream.Backends }}server {{ $server.Address }}:{{ $server.Port }}; + {{ range $server := $tcpServer.Upstream.Endpoints }}server {{ $server.Address }}:{{ $server.Port }}; {{ end }} } @@ -428,7 +428,7 @@ stream { # UDP services {{ range $i, $udpServer := .udpUpstreams }} upstream udp-{{ $udpServer.Upstream.Name }} { - {{ range $server := $udpServer.Upstream.Backends }}server {{ $server.Address }}:{{ $server.Port }}; + {{ range $server := $udpServer.Upstream.Endpoints }}server {{ $server.Address }}:{{ $server.Port }}; {{ end }} } diff --git a/core/pkg/ingress/controller/backend_ssl.go b/core/pkg/ingress/controller/backend_ssl.go index eea0539138..30efef5c46 100644 --- a/core/pkg/ingress/controller/backend_ssl.go +++ b/core/pkg/ingress/controller/backend_ssl.go @@ -31,8 +31,8 @@ import ( ssl "k8s.io/ingress/core/pkg/net/ssl" ) -// syncSecret keeps in sync Secrets used by Ingress rules with files to allow -// being used in controllers. +// syncSecret keeps in sync Secrets used by Ingress rules with the files on +// disk to allow being used in controllers. func (ic *GenericController) syncSecret(k interface{}) error { if ic.secretQueue.IsShuttingDown() { return nil @@ -67,7 +67,6 @@ func (ic *GenericController) syncSecret(k interface{}) error { key = k.(string) - // get secret secObj, exists, err := ic.secrLister.Store.GetByKey(key) if err != nil { return fmt.Errorf("error getting secret %v: %v", key, err) @@ -128,7 +127,7 @@ func (ic *GenericController) getPemCertificate(secretName string) (*ingress.SSLC return s, nil } -// check if secret is referenced in this controller's config +// secrReferenced checks if a secret is referenced or not by one or more Ingress rules func (ic *GenericController) secrReferenced(name, namespace string) bool { for _, ingIf := range ic.ingLister.Store.List() { ing := ingIf.(*extensions.Ingress) @@ -136,7 +135,6 @@ func (ic *GenericController) secrReferenced(name, namespace string) bool { if err == nil && str == fmt.Sprintf("%v/%v", namespace, name) { return true } - if ing.Namespace != namespace { continue } @@ -149,7 +147,7 @@ func (ic *GenericController) secrReferenced(name, namespace string) bool { return false } -// sslCertTracker ... +// sslCertTracker holds a store of referenced Secrets in Ingress rules type sslCertTracker struct { cache.ThreadSafeStore } diff --git a/core/pkg/ingress/controller/controller.go b/core/pkg/ingress/controller/controller.go index be0e782945..ce4fd07504 100644 --- a/core/pkg/ingress/controller/controller.go +++ b/core/pkg/ingress/controller/controller.go @@ -76,17 +76,7 @@ var ( reservedPorts = []string{"80", "443", "8181", "18080"} ) -// Interface holds the methods to handle an Ingress backend -type Interface interface { - Start() - Stop() error - - Info() string - - healthz.HealthzChecker -} - -// GenericController watches the kubernetes api and adds/removes services from the loadbalancer +// GenericController holds the boilerplate code required to build an Ingress controlller. type GenericController struct { healthz.HealthzChecker @@ -143,12 +133,13 @@ type Configuration struct { DefaultHealthzURL string // optional PublishService string - + // Backend is the particular implementation to be used. + // (for instance NGINX) Backend ingress.Controller } // newIngressController creates an Ingress controller -func newIngressController(config *Configuration) Interface { +func newIngressController(config *Configuration) *GenericController { eventBroadcaster := record.NewBroadcaster() eventBroadcaster.StartLogging(glog.Infof) @@ -280,7 +271,7 @@ func newIngressController(config *Configuration) Interface { IngressLister: ic.ingLister, }) - return ic + return &ic } func (ic *GenericController) controllersInSync() bool { @@ -365,8 +356,8 @@ func (ic *GenericController) sync(key interface{}) error { } } - upstreams, servers := ic.getUpstreamServers() - var passUpstreams []*ingress.SSLPassthroughUpstreams + upstreams, servers := ic.getBackendServers() + var passUpstreams []*ingress.SSLPassthroughBackend for _, server := range servers { if !server.SSLPassthrough { continue @@ -376,8 +367,8 @@ func (ic *GenericController) sync(key interface{}) error { if loc.Path != rootLocation { continue } - passUpstreams = append(passUpstreams, &ingress.SSLPassthroughUpstreams{ - Upstream: loc.Upstream, + passUpstreams = append(passUpstreams, &ingress.SSLPassthroughBackend{ + Upstream: loc.Backend, Host: server.Name, }) break @@ -388,8 +379,8 @@ func (ic *GenericController) sync(key interface{}) error { HealthzURL: ic.cfg.DefaultHealthzURL, Upstreams: upstreams, Servers: servers, - TCPUpstreams: ic.getTCPServices(), - UDPUpstreams: ic.getUDPServices(), + TCPEndpoints: ic.getTCPServices(), + UPDEndpoints: ic.getUDPServices(), PassthroughUpstreams: passUpstreams, }) if err != nil { @@ -497,7 +488,7 @@ func (ic *GenericController) getStreamServices(data map[string]string, proto api svc := svcObj.(*api.Service) - var endps []ingress.UpstreamServer + var endps []ingress.Endpoint targetPort, err := strconv.Atoi(svcPort) if err != nil { for _, sp := range svc.Spec.Ports { @@ -516,7 +507,7 @@ func (ic *GenericController) getStreamServices(data map[string]string, proto api } } - sort.Sort(ingress.UpstreamServerByAddrPort(endps)) + sort.Sort(ingress.EndpointByAddrPort(endps)) // tcp upstreams cannot contain empty upstreams and there is no // default backend equivalent for TCP @@ -527,9 +518,9 @@ func (ic *GenericController) getStreamServices(data map[string]string, proto api svcs = append(svcs, &ingress.Location{ Path: k, - Upstream: ingress.Upstream{ + Upstream: ingress.Backend{ Name: fmt.Sprintf("%v-%v-%v", svcNs, svcName, port), - Backends: endps, + Endpoints: endps, }, }) } @@ -540,21 +531,21 @@ func (ic *GenericController) getStreamServices(data map[string]string, proto api // getDefaultUpstream returns an upstream associated with the // default backend service. In case of error retrieving information // configure the upstream to return http code 503. -func (ic *GenericController) getDefaultUpstream() *ingress.Upstream { - upstream := &ingress.Upstream{ +func (ic *GenericController) getDefaultUpstream() *ingress.Backend { + upstream := &ingress.Backend{ Name: defUpstreamName, } svcKey := ic.cfg.DefaultService svcObj, svcExists, err := ic.svcLister.Indexer.GetByKey(svcKey) if err != nil { glog.Warningf("unexpected error searching the default backend %v: %v", ic.cfg.DefaultService, err) - upstream.Backends = append(upstream.Backends, newDefaultServer()) + upstream.Endpoints = append(upstream.Endpoints, newDefaultServer()) return upstream } if !svcExists { glog.Warningf("service %v does not exists", svcKey) - upstream.Backends = append(upstream.Backends, newDefaultServer()) + upstream.Endpoints = append(upstream.Endpoints, newDefaultServer()) return upstream } @@ -562,10 +553,10 @@ func (ic *GenericController) getDefaultUpstream() *ingress.Upstream { endps := ic.getEndpoints(svc, svc.Spec.Ports[0].TargetPort, api.ProtocolTCP, &healthcheck.Upstream{}) if len(endps) == 0 { glog.Warningf("service %v does not have any active endpoints", svcKey) - endps = []ingress.UpstreamServer{newDefaultServer()} + endps = []ingress.Endpoint{newDefaultServer()} } - upstream.Backends = append(upstream.Backends, endps...) + upstream.Endpoints = append(upstream.Endpoints, endps...) return upstream } @@ -579,9 +570,9 @@ func (c ingressByRevision) Less(i, j int) bool { return ir < jr } -// getUpstreamServers returns a list of Upstream and Server to be used by the backend +// getBackendServers returns a list of Upstream and Server to be used by the backend // An upstream can be used in multiple servers if the namespace, service name and port are the same -func (ic *GenericController) getUpstreamServers() ([]*ingress.Upstream, []*ingress.Server) { +func (ic *GenericController) getBackendServers() ([]*ingress.Backend, []*ingress.Server) { ings := ic.ingLister.Store.List() sort.Sort(ingressByRevision(ings)) @@ -699,19 +690,19 @@ func (ic *GenericController) getUpstreamServers() ([]*ingress.Upstream, []*ingre addLoc = false if !loc.IsDefBackend { - glog.V(3).Infof("avoiding replacement of ingress rule %v/%v location %v upstream %v (%v)", ing.Namespace, ing.Name, loc.Path, ups.Name, loc.Upstream.Name) + glog.V(3).Infof("avoiding replacement of ingress rule %v/%v location %v upstream %v (%v)", ing.Namespace, ing.Name, loc.Path, ups.Name, loc.Backend.Name) break } - glog.V(3).Infof("replacing ingress rule %v/%v location %v upstream %v (%v)", ing.Namespace, ing.Name, loc.Path, ups.Name, loc.Upstream.Name) - loc.Upstream = *ups + glog.V(3).Infof("replacing ingress rule %v/%v location %v upstream %v (%v)", ing.Namespace, ing.Name, loc.Path, ups.Name, loc.Backend.Name) + loc.Backend = *ups loc.IsDefBackend = false loc.BasicDigestAuth = *nginxAuth loc.RateLimit = *rl loc.Redirect = *locRew loc.SecureUpstream = secUpstream loc.Whitelist = *wl - loc.Upstream = *ups + loc.Backend = *ups loc.EnableCORS = eCORS loc.ExternalAuth = ra loc.Proxy = *prx @@ -744,16 +735,16 @@ func (ic *GenericController) getUpstreamServers() ([]*ingress.Upstream, []*ingre // TODO: find a way to make this more readable // The structs must be ordered to always generate the same file // if the content does not change. - aUpstreams := make([]*ingress.Upstream, 0, len(upstreams)) + aUpstreams := make([]*ingress.Backend, 0, len(upstreams)) for _, value := range upstreams { - if len(value.Backends) == 0 { + if len(value.Endpoints) == 0 { glog.V(3).Infof("upstream %v does not have any active endpoints. Using default backend", value.Name) - value.Backends = append(value.Backends, newDefaultServer()) + value.Endpoints = append(value.Endpoints, newDefaultServer()) } - sort.Sort(ingress.UpstreamServerByAddrPort(value.Backends)) + sort.Sort(ingress.EndpointByAddrPort(value.Endpoints)) aUpstreams = append(aUpstreams, value) } - sort.Sort(ingress.UpstreamByNameServers(aUpstreams)) + sort.Sort(ingress.BackendByNameServers(aUpstreams)) aServers := make([]*ingress.Server, 0, len(servers)) for _, value := range servers { @@ -781,8 +772,8 @@ func (ic *GenericController) getAuthCertificate(secretName string) (*authtls.SSL // createUpstreams creates the NGINX upstreams for each service referenced in // Ingress rules. The servers inside the upstream are endpoints. -func (ic *GenericController) createUpstreams(data []interface{}) map[string]*ingress.Upstream { - upstreams := make(map[string]*ingress.Upstream) +func (ic *GenericController) createUpstreams(data []interface{}) map[string]*ingress.Backend { + upstreams := make(map[string]*ingress.Backend) upstreams[defUpstreamName] = ic.getDefaultUpstream() upsDefaults := ic.cfg.Backend.UpstreamDefaults() @@ -803,7 +794,7 @@ func (ic *GenericController) createUpstreams(data []interface{}) map[string]*ing svcKey := fmt.Sprintf("%v/%v", ing.GetNamespace(), ing.Spec.Backend.ServiceName) endps, err := ic.serviceEndpoints(svcKey, ing.Spec.Backend.ServicePort.String(), hz) - upstreams[defBackend].Backends = append(upstreams[defBackend].Backends, endps...) + upstreams[defBackend].Endpoints = append(upstreams[defBackend].Endpoints, endps...) if err != nil { glog.Warningf("error creating upstream %v: %v", defBackend, err) } @@ -833,7 +824,7 @@ func (ic *GenericController) createUpstreams(data []interface{}) map[string]*ing glog.Warningf("error obtaining service endpoints: %v", err) continue } - upstreams[name].Backends = endp + upstreams[name].Endpoints = endp } } } @@ -844,10 +835,10 @@ func (ic *GenericController) createUpstreams(data []interface{}) map[string]*ing // serviceEndpoints returns the upstream servers (endpoints) associated // to a service. func (ic *GenericController) serviceEndpoints(svcKey, backendPort string, - hz *healthcheck.Upstream) ([]ingress.UpstreamServer, error) { + hz *healthcheck.Upstream) ([]ingress.Endpoint, error) { svcObj, svcExists, err := ic.svcLister.Indexer.GetByKey(svcKey) - var upstreams []ingress.UpstreamServer + var upstreams []ingress.Endpoint if err != nil { return upstreams, fmt.Errorf("error getting service %v from the cache: %v", svcKey, err) } @@ -878,7 +869,7 @@ func (ic *GenericController) serviceEndpoints(svcKey, backendPort string, return upstreams, nil } -func (ic *GenericController) createServers(data []interface{}, upstreams map[string]*ingress.Upstream) map[string]*ingress.Server { +func (ic *GenericController) createServers(data []interface{}, upstreams map[string]*ingress.Backend) map[string]*ingress.Server { servers := make(map[string]*ingress.Server) ngxProxy := *proxy.ParseAnnotations(ic.cfg.Backend.UpstreamDefaults(), nil) @@ -973,15 +964,15 @@ func (ic *GenericController) getEndpoints( s *api.Service, servicePort intstr.IntOrString, proto api.Protocol, - hz *healthcheck.Upstream) []ingress.UpstreamServer { + hz *healthcheck.Upstream) []ingress.Endpoint { glog.V(3).Infof("getting endpoints for service %v/%v and port %v", s.Namespace, s.Name, servicePort.String()) ep, err := ic.endpLister.GetServiceEndpoints(s) if err != nil { glog.Warningf("unexpected error obtaining service endpoints: %v", err) - return []ingress.UpstreamServer{} + return []ingress.Endpoint{} } - upsServers := []ingress.UpstreamServer{} + upsServers := []ingress.Endpoint{} for _, ss := range ep.Subsets { for _, epPort := range ss.Ports { @@ -1023,7 +1014,7 @@ func (ic *GenericController) getEndpoints( } for _, epAddress := range ss.Addresses { - ups := ingress.UpstreamServer{ + ups := ingress.Endpoint{ Address: epAddress.IP, Port: fmt.Sprintf("%v", targetPort), MaxFails: hz.MaxFails, diff --git a/core/pkg/ingress/controller/launch.go b/core/pkg/ingress/controller/launch.go index 420c664c82..7d4883a3c7 100644 --- a/core/pkg/ingress/controller/launch.go +++ b/core/pkg/ingress/controller/launch.go @@ -23,8 +23,8 @@ import ( kubectl_util "k8s.io/kubernetes/pkg/kubectl/cmd/util" ) -// NewIngressController returns a configured Ingress controller ready to start -func NewIngressController(backend ingress.Controller) Interface { +// NewIngressController returns a configured Ingress controller +func NewIngressController(backend ingress.Controller) *GenericController { var ( flags = pflag.NewFlagSet("", pflag.ExitOnError) @@ -33,7 +33,7 @@ func NewIngressController(backend ingress.Controller) Interface { namespace/name. The controller uses the first node port of this Service for the default backend.`) - ingressClass = flags.String("ingress-class", "nginx", + ingressClass = flags.String("ingress-class", "", `Name of the ingress class to route through this controller.`) configMap = flags.String("configmap", "", @@ -49,7 +49,7 @@ func NewIngressController(backend ingress.Controller) Interface { The key in the map indicates the external port to be used. The value is the name of the service with the format namespace/serviceName and the port of the service could be a number of the name of the port. - The ports 80 and 443 are not allowed as external ports. This ports are reserved for nginx`) + The ports 80 and 443 are not allowed as external ports. This ports are reserved for the backend`) udpConfigMapName = flags.String("udp-services-configmap", "", `Name of the ConfigMap that contains the definition of the UDP services to expose. @@ -152,7 +152,7 @@ func NewIngressController(backend ingress.Controller) Interface { return ic } -func registerHandlers(enableProfiling bool, port int, ic Interface) { +func registerHandlers(enableProfiling bool, port int, ic *GenericController) { mux := http.NewServeMux() healthz.InstallHandler(mux, ic) diff --git a/core/pkg/ingress/controller/util.go b/core/pkg/ingress/controller/util.go index 68dafb6d76..3d5c7619d3 100644 --- a/core/pkg/ingress/controller/util.go +++ b/core/pkg/ingress/controller/util.go @@ -25,16 +25,16 @@ import ( "k8s.io/kubernetes/pkg/apis/extensions" ) -// newDefaultServer return an UpstreamServer to be use as default server that returns 503. -func newDefaultServer() ingress.UpstreamServer { - return ingress.UpstreamServer{Address: "127.0.0.1", Port: "8181"} +// newDefaultServer return an BackendServer to be use as default server that returns 503. +func newDefaultServer() ingress.Endpoint { + return ingress.Endpoint{Address: "127.0.0.1", Port: "8181"} } // newUpstream creates an upstream without servers. -func newUpstream(name string) *ingress.Upstream { - return &ingress.Upstream{ +func newUpstream(name string) *ingress.Backend { + return &ingress.Backend{ Name: name, - Backends: []ingress.UpstreamServer{}, + Endpoints: []ingress.Endpoint{}, } } diff --git a/core/pkg/ingress/types.go b/core/pkg/ingress/types.go deleted file mode 100644 index 5eb83670e9..0000000000 --- a/core/pkg/ingress/types.go +++ /dev/null @@ -1,214 +0,0 @@ -/* -Copyright 2015 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 ingress - -import ( - "os/exec" - - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/unversioned" - - "k8s.io/ingress/core/pkg/ingress/annotations/auth" - "k8s.io/ingress/core/pkg/ingress/annotations/authreq" - "k8s.io/ingress/core/pkg/ingress/annotations/authtls" - "k8s.io/ingress/core/pkg/ingress/annotations/ipwhitelist" - "k8s.io/ingress/core/pkg/ingress/annotations/proxy" - "k8s.io/ingress/core/pkg/ingress/annotations/ratelimit" - "k8s.io/ingress/core/pkg/ingress/annotations/rewrite" - "k8s.io/ingress/core/pkg/ingress/defaults" -) - -var ( - // DefaultSSLDirectory defines the location where the SSL certificates will be generated - DefaultSSLDirectory = "/ingress-controller/ssl" -) - -// Controller ... -type Controller interface { - // Start returns the command is executed to start the backend. - // The command must run in foreground. - Start() - // Stop stops the backend - Stop() error - // Restart reload the backend with the a configuration file returning - // the combined output of Stdout and Stderr - Restart(data []byte) ([]byte, error) - // Tests returns a commands that checks if the configuration file is valid - // Example: nginx -t -c - Test(file string) *exec.Cmd - // OnUpdate callback invoked from the sync queue https://k8s.io/ingress/core/blob/master/pkg/ingress/controller/controller.go#L355 - // when an update occurs. This is executed frequently because Ingress - // controllers watches changes in: - // - Ingresses: main work - // - Secrets: referenced from Ingress rules with TLS configured - // - ConfigMaps: where the controller reads custom configuration - // - Services: referenced from Ingress rules and required to obtain - // information about ports and annotations - // - Endpoints: referenced from Services and what the backend uses - // to route traffic - // - // ConfigMap content of --configmap - // Configuration returns the translation from Ingress rules containing - // information about all the upstreams (service endpoints ) "virtual" - // servers (FQDN) - // and all the locations inside each server. Each location contains - // information about all the annotations were configured - // https://k8s.io/ingress/core/blob/master/pkg/ingress/types.go#L48 - OnUpdate(*api.ConfigMap, Configuration) ([]byte, error) - // UpstreamDefaults returns the minimum settings required to configure the - // communication to upstream servers (endpoints) - UpstreamDefaults() defaults.Backend - // IsReloadRequired checks if the backend must be reloaded or not. - // The parameter contains the new rendered template - IsReloadRequired([]byte) bool - // Info returns information about the ingress controller - // This can include build version, repository, etc. - Info() string -} - -// Configuration describes -type Configuration struct { - HealthzURL string - Upstreams []*Upstream - Servers []*Server - TCPUpstreams []*Location - UDPUpstreams []*Location - PassthroughUpstreams []*SSLPassthroughUpstreams -} - -// Upstream describes an upstream server (endpoint) -type Upstream struct { - // Secure indicates if the communication with the en - Secure bool - // Name represents an unique api.Service name formatted - // as -- - Name string - // Backends - Backends []UpstreamServer -} - -// SSLPassthroughUpstreams describes an SSL upstream server configured -// as passthrough (no TLS termination) -type SSLPassthroughUpstreams struct { - Upstream - - Host string -} - -// UpstreamByNameServers sorts upstreams by name -type UpstreamByNameServers []*Upstream - -func (c UpstreamByNameServers) Len() int { return len(c) } -func (c UpstreamByNameServers) Swap(i, j int) { c[i], c[j] = c[j], c[i] } -func (c UpstreamByNameServers) Less(i, j int) bool { - return c[i].Name < c[j].Name -} - -// UpstreamServer describes a server in an upstream -type UpstreamServer struct { - // Address IP address of the endpoint - Address string - Port string - // MaxFails returns the maximum number of check failures - // allowed before this should be considered dow. - // Setting 0 indicates that the check is performed by a Kubernetes probe - MaxFails int - FailTimeout int -} - -// Server describes a virtual server -type Server struct { - Name string - SSL bool - SSLPassthrough bool - SSLCertificate string - //SSLCertificateKey string - SSLPemChecksum string - Locations []*Location -} - -// Location describes a server location -type Location struct { - IsDefBackend bool - SecureUpstream bool - EnableCORS bool - Path string - Upstream Upstream - BasicDigestAuth auth.BasicDigest - RateLimit ratelimit.RateLimit - Redirect rewrite.Redirect - Whitelist ipwhitelist.SourceRange - ExternalAuth authreq.External - Proxy proxy.Configuration - CertificateAuth authtls.SSLCert -} - -// UpstreamServerByAddrPort sorts upstream servers by address and port -type UpstreamServerByAddrPort []UpstreamServer - -func (c UpstreamServerByAddrPort) Len() int { return len(c) } -func (c UpstreamServerByAddrPort) Swap(i, j int) { c[i], c[j] = c[j], c[i] } -func (c UpstreamServerByAddrPort) Less(i, j int) bool { - iName := c[i].Address - jName := c[j].Address - if iName != jName { - return iName < jName - } - - iU := c[i].Port - jU := c[j].Port - return iU < jU -} - -// ServerByName sorts server by name -type ServerByName []*Server - -func (c ServerByName) Len() int { return len(c) } -func (c ServerByName) Swap(i, j int) { c[i], c[j] = c[j], c[i] } -func (c ServerByName) Less(i, j int) bool { - return c[i].Name < c[j].Name -} - -// LocationByPath sorts location by path -// Location / is the last one -type LocationByPath []*Location - -func (c LocationByPath) Len() int { return len(c) } -func (c LocationByPath) Swap(i, j int) { c[i], c[j] = c[j], c[i] } -func (c LocationByPath) Less(i, j int) bool { - return c[i].Path > c[j].Path -} - -// SSLCert describes a SSL certificate to be used in a server -type SSLCert struct { - api.ObjectMeta - - //CertFileName string - //KeyFileName string - CAFileName string - - // PemFileName contains the path to the file with the certificate and key concatenated - PemFileName string - // PemSHA contains the sha1 of the pem file. - // This is used to detect changes in the secret that contains the certificates - PemSHA string - // CN contains all the common names defined in the SSL certificate - CN []string -} - -// GetObjectKind implements the ObjectKind interface as a noop -func (s SSLCert) GetObjectKind() unversioned.ObjectKind { return unversioned.EmptyObjectKind } From 5a8e09073683e3ce5c2208b5be084a7db1807d70 Mon Sep 17 00:00:00 2001 From: Manuel de Brito Fontes Date: Wed, 16 Nov 2016 15:24:26 -0300 Subject: [PATCH 3/5] Add Generic interface --- .travis.yml | 2 +- controllers/nginx/pkg/cmd/controller/nginx.go | 73 +- controllers/nginx/pkg/config/config.go | 20 +- controllers/nginx/pkg/template/configmap.go | 10 +- controllers/nginx/pkg/template/template.go | 86 +- .../nginx/pkg/template/template_test.go | 76 +- controllers/nginx/rootfs/Dockerfile | 2 +- .../rootfs/etc/nginx/template/nginx.tmpl | 165 +- controllers/nginx/test/data/config.json | 57259 ++++++++++++++++ core/pkg/ingress/annotations/auth/main.go | 12 +- core/pkg/ingress/annotations/authreq/main.go | 9 +- core/pkg/ingress/annotations/authtls/main.go | 14 +- core/pkg/ingress/annotations/cors/main.go | 4 +- .../ingress/annotations/healthcheck/main.go | 4 +- .../ingress/annotations/ipwhitelist/main.go | 8 +- core/pkg/ingress/annotations/proxy/main.go | 8 +- .../pkg/ingress/annotations/ratelimit/main.go | 16 +- core/pkg/ingress/annotations/rewrite/main.go | 10 +- .../annotations/secureupstream/main.go | 4 +- .../annotations/sslpassthrough/main.go | 4 +- core/pkg/ingress/controller/backend_ssl.go | 3 +- core/pkg/ingress/controller/controller.go | 86 +- core/pkg/ingress/controller/launch.go | 10 +- core/pkg/ingress/controller/named_port.go | 4 +- core/pkg/ingress/controller/util.go | 6 +- core/pkg/ingress/doc.go | 63 + core/pkg/ingress/sort_ingress.go | 85 + core/pkg/ingress/status/status.go | 10 +- core/pkg/ingress/types.go | 243 + core/pkg/net/ssl/ssl.go | 4 +- hack/e2e-internal/e2e-down.sh | 14 - hack/e2e-internal/e2e-env.sh | 21 - hack/e2e-internal/e2e-status.sh | 11 - hack/e2e-internal/e2e-up.sh | 55 - hack/e2e-internal/ginkgo-e2e.sh | 3 - hack/e2e.go | 285 - 36 files changed, 58014 insertions(+), 675 deletions(-) create mode 100644 controllers/nginx/test/data/config.json create mode 100644 core/pkg/ingress/doc.go create mode 100644 core/pkg/ingress/sort_ingress.go create mode 100644 core/pkg/ingress/types.go delete mode 100755 hack/e2e-internal/e2e-down.sh delete mode 100755 hack/e2e-internal/e2e-env.sh delete mode 100755 hack/e2e-internal/e2e-status.sh delete mode 100755 hack/e2e-internal/e2e-up.sh delete mode 100755 hack/e2e-internal/ginkgo-e2e.sh delete mode 100644 hack/e2e.go diff --git a/.travis.yml b/.travis.yml index a55e7c8c75..b9c2eca32a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,5 +30,5 @@ script: # enable kubernetes/ingress in # coveralls.io and add cover task - make fmt lint vet test - - make controllers controllers-images + #- make controllers controllers-images #- make test-e2e diff --git a/controllers/nginx/pkg/cmd/controller/nginx.go b/controllers/nginx/pkg/cmd/controller/nginx.go index eb077a74e1..757e6aaaff 100644 --- a/controllers/nginx/pkg/cmd/controller/nginx.go +++ b/controllers/nginx/pkg/cmd/controller/nginx.go @@ -25,14 +25,16 @@ import ( "github.com/golang/glog" + "k8s.io/kubernetes/pkg/api" + "k8s.io/ingress/core/pkg/ingress" "k8s.io/ingress/core/pkg/ingress/defaults" + "errors" + "k8s.io/ingress/controllers/nginx/pkg/config" ngx_template "k8s.io/ingress/controllers/nginx/pkg/template" "k8s.io/ingress/controllers/nginx/pkg/version" - - "k8s.io/kubernetes/pkg/api" ) var ( @@ -75,6 +77,8 @@ Error loading new template : %v } n.t = ngxTpl + go n.Start() + return n } @@ -85,7 +89,7 @@ type NGINXController struct { binary string } -// Start ... +// Start start a new NGINX master process running in foreground. func (n NGINXController) Start() { glog.Info("starting NGINX process...") cmd := exec.Command(n.binary, "-c", cfgPath) @@ -99,14 +103,13 @@ func (n NGINXController) Start() { } } -// Stop ... -func (n NGINXController) Stop() error { - n.t.Close() - return exec.Command(n.binary, "-s", "stop").Run() -} +// Reload checks if the running configuration file is different +// to the specified and reload nginx if required +func (n NGINXController) Reload(data []byte) ([]byte, error) { + if !n.isReloadRequired(data) { + return nil, fmt.Errorf("Reload not required") + } -// Restart ... -func (n NGINXController) Restart(data []byte) ([]byte, error) { err := ioutil.WriteFile(cfgPath, data, 0644) if err != nil { return nil, err @@ -120,15 +123,15 @@ func (n NGINXController) Test(file string) *exec.Cmd { return exec.Command(n.binary, "-t", "-c", file) } -// UpstreamDefaults returns the nginx defaults -func (n NGINXController) UpstreamDefaults() defaults.Backend { +// BackendDefaults returns the nginx defaults +func (n NGINXController) BackendDefaults() defaults.Backend { d := config.NewDefault() return d.Backend } // IsReloadRequired check if the new configuration file is different // from the current one. -func (n NGINXController) IsReloadRequired(data []byte) bool { +func (n NGINXController) isReloadRequired(data []byte) bool { in, err := os.Open(cfgPath) if err != nil { return false @@ -167,8 +170,13 @@ func (n NGINXController) IsReloadRequired(data []byte) bool { } // Info return build information -func (n NGINXController) Info() string { - return fmt.Sprintf("build version %v from repo %v commit %v", version.RELEASE, version.REPO, version.COMMIT) +func (n NGINXController) Info() *ingress.BackendInfo { + return &ingress.BackendInfo{ + Name: "NGINX", + Release: version.RELEASE, + Build: version.COMMIT, + Repository: version.REPO, + } } // testTemplate checks if the NGINX configuration inside the byte array is valid @@ -183,12 +191,13 @@ func (n NGINXController) testTemplate(cfg []byte) error { out, err := n.Test(tmpfile.Name()).CombinedOutput() if err != nil { // this error is different from the rest because it must be clear why nginx is not working - return fmt.Errorf(` + oe := fmt.Sprintf(` ------------------------------------------------------------------------------- Error: %v %v ------------------------------------------------------------------------------- `, err, string(out)) + return errors.New(oe) } os.Remove(tmpfile.Name()) @@ -207,9 +216,9 @@ func (n NGINXController) OnUpdate(cmap *api.ConfigMap, ingressCfg ingress.Config var longestName int var serverNames int for _, srv := range ingressCfg.Servers { - serverNames += len([]byte(srv.Name)) - if longestName < len(srv.Name) { - longestName = len(srv.Name) + serverNames += len([]byte(srv.Hostname)) + if longestName < len(srv.Hostname) { + longestName = len(srv.Hostname) } } @@ -234,21 +243,17 @@ func (n NGINXController) OnUpdate(cmap *api.ConfigMap, ingressCfg ingress.Config cfg.ServerNameHashMaxSize = serverNameHashMaxSize } - conf := make(map[string]interface{}) - // adjust the size of the backlog - conf["backlogSize"] = sysctlSomaxconn() - conf["upstreams"] = ingressCfg.Upstreams - conf["passthroughUpstreams"] = ingressCfg.PassthroughUpstreams - conf["servers"] = ingressCfg.Servers - conf["tcpUpstreams"] = ingressCfg.TCPEndpoints - conf["udpUpstreams"] = ingressCfg.UPDEndpoints - conf["healthzURL"] = ingressCfg.HealthzURL - conf["defResolver"] = cfg.Resolver - conf["sslDHParam"] = "" - conf["customErrors"] = len(cfg.CustomHTTPErrors) > 0 - conf["cfg"] = ngx_template.StandarizeKeyNames(cfg) - - return n.t.Write(conf, n.testTemplate) + return n.t.Write(config.TemplateConfig{ + BacklogSize: sysctlSomaxconn(), + Backends: ingressCfg.Backends, + PassthrougBackends: ingressCfg.PassthroughBackends, + Servers: ingressCfg.Servers, + TCPBackends: ingressCfg.TCPEndpoints, + UDPBackends: ingressCfg.UPDEndpoints, + HealthzURI: "/healthz", + CustomErrors: len(cfg.CustomHTTPErrors) > 0, + Cfg: cfg, + }, n.testTemplate) } // http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 diff --git a/controllers/nginx/pkg/config/config.go b/controllers/nginx/pkg/config/config.go index 3ef7ea7bbe..8afeca499e 100644 --- a/controllers/nginx/pkg/config/config.go +++ b/controllers/nginx/pkg/config/config.go @@ -19,9 +19,10 @@ package config import ( "runtime" - "k8s.io/ingress/core/pkg/ingress/defaults" - "github.com/golang/glog" + + "k8s.io/ingress/core/pkg/ingress" + "k8s.io/ingress/core/pkg/ingress/defaults" ) const ( @@ -216,8 +217,7 @@ type Configuration struct { WorkerProcesses int `structs:"worker-processes,omitempty"` } -// NewDefault returns the default configuration contained -// in the file default-conf.json +// NewDefault returns the default nginx configuration func NewDefault() Configuration { cfg := Configuration{ BodySize: bodySize, @@ -264,3 +264,15 @@ func NewDefault() Configuration { return cfg } + +type TemplateConfig struct { + BacklogSize int + Backends []*ingress.Backend + PassthrougBackends []*ingress.SSLPassthroughBackend + Servers []*ingress.Server + TCPBackends []*ingress.Location + UDPBackends []*ingress.Location + HealthzURI string + CustomErrors bool + Cfg Configuration +} diff --git a/controllers/nginx/pkg/template/configmap.go b/controllers/nginx/pkg/template/configmap.go index b110b403c2..09bce6d006 100644 --- a/controllers/nginx/pkg/template/configmap.go +++ b/controllers/nginx/pkg/template/configmap.go @@ -27,10 +27,10 @@ import ( "github.com/mitchellh/mapstructure" go_camelcase "github.com/segmentio/go-camelcase" + "k8s.io/kubernetes/pkg/api" + "k8s.io/ingress/controllers/nginx/pkg/config" "k8s.io/ingress/core/pkg/ingress/defaults" - - "k8s.io/kubernetes/pkg/api" ) const ( @@ -50,9 +50,9 @@ func ReadConfig(conf *api.ConfigMap) config.Configuration { return config.NewDefault() } - var errors []int - var skipUrls []string - var whitelist []string + errors := make([]int, 0) + skipUrls := make([]string, 0) + whitelist := make([]string, 0) if val, ok := conf.Data[customHTTPErrors]; ok { delete(conf.Data, customHTTPErrors) diff --git a/controllers/nginx/pkg/template/template.go b/controllers/nginx/pkg/template/template.go index 7485b69628..59c6c844f7 100644 --- a/controllers/nginx/pkg/template/template.go +++ b/controllers/nginx/pkg/template/template.go @@ -27,6 +27,7 @@ import ( "github.com/golang/glog" + "k8s.io/ingress/controllers/nginx/pkg/config" "k8s.io/ingress/core/pkg/ingress" "k8s.io/ingress/core/pkg/watch" ) @@ -73,12 +74,19 @@ func (t *Template) Close() { // Write populates a buffer using a template with NGINX configuration // and the servers and upstreams created by Ingress rules -func (t *Template) Write(conf map[string]interface{}, - isValidTemplate func([]byte) error) ([]byte, error) { - +func (t *Template) Write(conf config.TemplateConfig, isValidTemplate func([]byte) error) ([]byte, error) { defer t.tmplBuf.Reset() defer t.outCmdBuf.Reset() + defer func() { + if t.s < t.tmplBuf.Cap() { + glog.V(2).Infof("adjusting template buffer size from %v to %v", t.s, t.tmplBuf.Cap()) + t.s = t.tmplBuf.Cap() + t.tmplBuf = bytes.NewBuffer(make([]byte, 0, t.tmplBuf.Cap())) + t.outCmdBuf = bytes.NewBuffer(make([]byte, 0, t.outCmdBuf.Cap())) + } + }() + if glog.V(3) { b, err := json.Marshal(conf) if err != nil { @@ -88,12 +96,8 @@ func (t *Template) Write(conf map[string]interface{}, } err := t.tmpl.Execute(t.tmplBuf, conf) - - if t.s < t.tmplBuf.Cap() { - glog.V(2).Infof("adjusting template buffer size from %v to %v", t.s, t.tmplBuf.Cap()) - t.s = t.tmplBuf.Cap() - t.tmplBuf = bytes.NewBuffer(make([]byte, 0, t.tmplBuf.Cap())) - t.outCmdBuf = bytes.NewBuffer(make([]byte, 0, t.outCmdBuf.Cap())) + if err != nil { + return nil, err } // squeezes multiple adjacent empty lines to be single @@ -124,12 +128,12 @@ var ( } return true }, - "buildLocation": buildLocation, - "buildAuthLocation": buildAuthLocation, - "buildProxyPass": buildProxyPass, - "buildRateLimitZones": buildRateLimitZones, - "buildRateLimit": buildRateLimit, - "getSSPassthroughUpstream": getSSPassthroughUpstream, + "buildLocation": buildLocation, + "buildAuthLocation": buildAuthLocation, + "buildProxyPass": buildProxyPass, + "buildRateLimitZones": buildRateLimitZones, + "buildRateLimit": buildRateLimit, + "buildSSPassthroughUpstreams": buildSSPassthroughUpstreams, "contains": strings.Contains, "hasPrefix": strings.HasPrefix, @@ -139,13 +143,32 @@ var ( } ) -func getSSPassthroughUpstream(input interface{}) string { - s, ok := input.(*ingress.Server) - if !ok { - return "" +func buildSSPassthroughUpstreams(b interface{}, sslb interface{}) string { + backends := b.([]*ingress.Backend) + sslBackends := sslb.([]*ingress.SSLPassthroughBackend) + buf := bytes.NewBuffer(make([]byte, 0, 10)) + + // multiple services can use the same upstream. + // avoid duplications using a map[name]=true + u := make(map[string]bool) + for _, passthrough := range sslBackends { + if u[passthrough.Backend] { + continue + } + u[passthrough.Backend] = true + fmt.Fprintf(buf, "upstream %v {\n", passthrough.Backend) + for _, backend := range backends { + if backend.Name == passthrough.Backend { + for _, server := range backend.Endpoints { + fmt.Fprintf(buf, "\t\tserver %v:%v;\n", server.Address, server.Port) + } + break + } + } + fmt.Fprint(buf, "\t}\n\n") } - return s.Name + return buf.String() } // buildLocation produces the location string, if the ingress has redirects @@ -184,20 +207,27 @@ func buildAuthLocation(input interface{}) string { // (specified through the ingress.kubernetes.io/rewrite-to annotation) // If the annotation ingress.kubernetes.io/add-base-url:"true" is specified it will // add a base tag in the head of the response from the service -func buildProxyPass(input interface{}) string { - location, ok := input.(*ingress.Location) +func buildProxyPass(b interface{}, loc interface{}) string { + backends := b.([]*ingress.Backend) + location, ok := loc.(*ingress.Location) if !ok { return "" } path := location.Path - proto := "http" - if location.SecureUpstream { - proto = "https" + + for _, backend := range backends { + if backend.Name == location.Backend { + if backend.Secure { + proto = "https" + } + break + } } + // defProxyPass returns the default proxy_pass, just the name of the upstream - defProxyPass := fmt.Sprintf("proxy_pass %s://%s;", proto, location.Backend.Name) + defProxyPass := fmt.Sprintf("proxy_pass %s://%s;", proto, location.Backend) // if the path in the ingress rule is equals to the target: no special rewrite if path == location.Redirect.Target { return defProxyPass @@ -227,13 +257,13 @@ func buildProxyPass(input interface{}) string { rewrite %s(.*) /$1 break; rewrite %s / break; proxy_pass %s://%s; - %v`, path, location.Path, proto, location.Backend.Name, abu) + %v`, path, location.Path, proto, location.Backend, abu) } return fmt.Sprintf(` rewrite %s(.*) %s/$1 break; proxy_pass %s://%s; - %v`, path, location.Redirect.Target, proto, location.Backend.Name, abu) + %v`, path, location.Redirect.Target, proto, location.Backend, abu) } // default proxy_pass diff --git a/controllers/nginx/pkg/template/template_test.go b/controllers/nginx/pkg/template/template_test.go index 4dbb73e4cc..fde02e3ef6 100644 --- a/controllers/nginx/pkg/template/template_test.go +++ b/controllers/nginx/pkg/template/template_test.go @@ -17,14 +17,21 @@ limitations under the License. package template import ( + "encoding/json" + "os" + "path" "strings" "testing" + "io/ioutil" + + "k8s.io/ingress/controllers/nginx/pkg/config" "k8s.io/ingress/core/pkg/ingress" "k8s.io/ingress/core/pkg/ingress/annotations/rewrite" ) var ( + // TODO: add tests for secure endpoints tmplFuncTestcases = map[string]struct { Path string Target string @@ -88,12 +95,77 @@ func TestBuildProxyPass(t *testing.T) { loc := &ingress.Location{ Path: tc.Path, Redirect: rewrite.Redirect{Target: tc.Target, AddBaseURL: tc.AddBaseURL}, - Upstream: ingress.Backend{Name: "upstream-name"}, + Backend: "upstream-name", } - pp := buildProxyPass(loc) + pp := buildProxyPass([]*ingress.Backend{}, loc) if !strings.EqualFold(tc.ProxyPass, pp) { t.Errorf("%s: expected \n'%v'\nbut returned \n'%v'", k, tc.ProxyPass, pp) } } } + +func TestTemplateWithData(t *testing.T) { + pwd, _ := os.Getwd() + f, err := os.Open(path.Join(pwd, "../../test/data/config.json")) + if err != nil { + t.Errorf("unexpected error reading json file: %v", err) + } + defer f.Close() + data, err := ioutil.ReadFile(f.Name()) + if err != nil { + t.Error("unexpected error reading json file: ", err) + } + var dat config.TemplateConfig + if err := json.Unmarshal(data, &dat); err != nil { + t.Errorf("unexpected error unmarshalling json: %v", err) + } + + tf, err := os.Open(path.Join(pwd, "../../rootfs/etc/nginx/template/nginx.tmpl")) + if err != nil { + t.Errorf("unexpected error reading json file: %v", err) + } + defer tf.Close() + + ngxTpl, err := NewTemplate(tf.Name(), func() {}) + if err != nil { + t.Errorf("invalid NGINX template: %v", err) + } + + _, err = ngxTpl.Write(dat, func(b []byte) error { return nil }) + if err != nil { + t.Errorf("invalid NGINX template: %v", err) + } +} + +func BenchmarkTemplateWithData(b *testing.B) { + pwd, _ := os.Getwd() + f, err := os.Open(path.Join(pwd, "../../test/data/config.json")) + if err != nil { + b.Errorf("unexpected error reading json file: %v", err) + } + defer f.Close() + data, err := ioutil.ReadFile(f.Name()) + if err != nil { + b.Error("unexpected error reading json file: ", err) + } + var dat config.TemplateConfig + if err := json.Unmarshal(data, &dat); err != nil { + b.Errorf("unexpected error unmarshalling json: %v", err) + } + + tf, err := os.Open(path.Join(pwd, "../../rootfs/etc/nginx/template/nginx.tmpl")) + if err != nil { + b.Errorf("unexpected error reading json file: %v", err) + } + defer tf.Close() + + ngxTpl, err := NewTemplate(tf.Name(), func() {}) + if err != nil { + b.Errorf("invalid NGINX template: %v", err) + } + + for i := 0; i < b.N; i++ { + ngxTpl.Write(dat, func(b []byte) error { return nil }) + } +} diff --git a/controllers/nginx/rootfs/Dockerfile b/controllers/nginx/rootfs/Dockerfile index f5a6abaf75..c7e4180ff2 100644 --- a/controllers/nginx/rootfs/Dockerfile +++ b/controllers/nginx/rootfs/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM gcr.io/google_containers/nginx-slim:0.10 +FROM gcr.io/google_containers/nginx-slim:0.11 RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y \ diffutils \ diff --git a/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl b/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl index b2330acd39..30774f6f6a 100644 --- a/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl +++ b/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl @@ -1,20 +1,20 @@ -{{ $cfg := .cfg }}{{ $healthzURL := .healthzURL }} +{{ $cfg := .Cfg }}{{ $healthzURI := .HealthzURI }}{{ $backends := .Backends }} daemon off; -worker_processes {{ $cfg.workerProcesses }}; +worker_processes {{ $cfg.WorkerProcesses }}; pid /run/nginx.pid; worker_rlimit_nofile 131072; events { multi_accept on; - worker_connections {{ $cfg.maxWorkerConnections }}; + worker_connections {{ $cfg.MaxWorkerConnections }}; use epoll; } http { {{/* we use the value of the header X-Forwarded-For to be able to use the geo_ip module */}} - {{ if $cfg.useProxyProtocol }} - set_real_ip_from {{ $cfg.proxyRealIpCidr }}; + {{ if $cfg.UseProxyProtocol }} + set_real_ip_from {{ $cfg.ProxyRealIpCidr }}; real_ip_header proxy_protocol; {{ else }} real_ip_header X-Forwarded-For; @@ -30,8 +30,8 @@ http { geoip_city /etc/nginx/GeoLiteCity.dat; geoip_proxy_recursive on; - {{ if $cfg.enableVtsStatus }} - vhost_traffic_status_zone shared:vhost_traffic_status:{{ $cfg.vtsStatusZoneSize }}; + {{ if $cfg.EnableVtsStatus }} + vhost_traffic_status_zone shared:vhost_traffic_status:{{ $cfg.VtsStatusZoneSize }}; vhost_traffic_status_filter_by_set_key $geoip_country_code country::*; {{ end }} @@ -50,43 +50,43 @@ http { reset_timedout_connection on; - keepalive_timeout {{ $cfg.keepAlive }}s; + keepalive_timeout {{ $cfg.KeepAlive }}s; types_hash_max_size 2048; - server_names_hash_max_size {{ $cfg.serverNameHashMaxSize }}; - server_names_hash_bucket_size {{ $cfg.serverNameHashBucketSize }}; - map_hash_bucket_size {{ $cfg.mapHashBucketSize }}; + server_names_hash_max_size {{ $cfg.ServerNameHashMaxSize }}; + server_names_hash_bucket_size {{ $cfg.ServerNameHashBucketSize }}; + map_hash_bucket_size {{ $cfg.MapHashBucketSize }}; include /etc/nginx/mime.types; default_type text/html; - {{ if $cfg.useGzip }} + {{ if $cfg.UseGzip }} gzip on; gzip_comp_level 5; gzip_http_version 1.1; gzip_min_length 256; - gzip_types {{ $cfg.gzipTypes }}; + gzip_types {{ $cfg.GzipTypes }}; gzip_proxied any; {{ end }} - client_max_body_size "{{ $cfg.bodySize }}"; + client_max_body_size "{{ $cfg.BodySize }}"; - log_format upstreaminfo '{{ if $cfg.useProxyProtocol }}$proxy_protocol_addr{{ else }}$remote_addr{{ end }} - ' + log_format upstreaminfo '{{ if $cfg.UseProxyProtocol }}$proxy_protocol_addr{{ else }}$remote_addr{{ end }} - ' '[$proxy_add_x_forwarded_for] - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" ' '$request_length $request_time [$proxy_upstream_name] $upstream_addr $upstream_response_length $upstream_response_time $upstream_status'; {{/* map urls that should not appear in access.log */}} {{/* http://nginx.org/en/docs/http/ngx_http_log_module.html#access_log */}} map $request $loggable { - {{ range $reqUri := $cfg.skipAccessLogUrls }} + {{ range $reqUri := $cfg.SkipAccessLogURLs }} {{ $reqUri }} 0;{{ end }} default 1; } access_log /var/log/nginx/access.log upstreaminfo if=$loggable; - error_log /var/log/nginx/error.log {{ $cfg.errorLogLevel }}; + error_log /var/log/nginx/error.log {{ $cfg.ErrorLogLevel }}; - {{ if not (empty .defResolver) }}# Custom dns resolver. - resolver {{ .defResolver }} valid=30s; + {{ if not (empty $cfg.Resolver) }}# Custom dns resolver. + resolver {{ $cfg.Resolver }} valid=30s; resolver_timeout 10s; {{ end }} @@ -98,14 +98,14 @@ http { {{/* normal nginx behavior we have to use this approach. */}} # Retain the default nginx handling of requests without a "Connection" header map $http_upgrade $connection_upgrade { - default upgrade; - '' close; + default upgrade; + '' close; } # trust http_x_forwarded_proto headers correctly indicate ssl offloading map $http_x_forwarded_proto $pass_access_scheme { - default $http_x_forwarded_proto; - '' $scheme; + default $http_x_forwarded_proto; + '' $scheme; } # Map a response error watching the header Content-Type @@ -124,51 +124,51 @@ http { } server_name_in_redirect off; - port_in_redirect off; + port_in_redirect off; - ssl_protocols {{ $cfg.sslProtocols }}; + ssl_protocols {{ $cfg.SSLProtocols }}; # turn on session caching to drastically improve performance - {{ if $cfg.sslSessionCache }} - ssl_session_cache builtin:1000 shared:SSL:{{ $cfg.sslSessionCacheSize }}; - ssl_session_timeout {{ $cfg.sslSessionTimeout }}; + {{ if $cfg.SSLSessionCache }} + ssl_session_cache builtin:1000 shared:SSL:{{ $cfg.SSLSessionCacheSize }}; + ssl_session_timeout {{ $cfg.SSLSessionTimeout }}; {{ end }} # allow configuring ssl session tickets - ssl_session_tickets {{ if $cfg.sslSessionTickets }}on{{ else }}off{{ end }}; + ssl_session_tickets {{ if $cfg.SSLSessionTickets }}on{{ else }}off{{ end }}; # slightly reduce the time-to-first-byte - ssl_buffer_size {{ $cfg.sslBufferSize }}; + ssl_buffer_size {{ $cfg.SSLBufferSize }}; - {{ if not (empty $cfg.sslCiphers) }} + {{ if not (empty $cfg.SSLCiphers) }} # allow configuring custom ssl ciphers - ssl_ciphers '{{ $cfg.sslCiphers }}'; + ssl_ciphers '{{ $cfg.SSLCiphers }}'; ssl_prefer_server_ciphers on; {{ end }} - {{ if not (empty .sslDHParam) }} + {{ if not (empty $cfg.SSLDHParam) }} # allow custom DH file http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_dhparam - ssl_dhparam {{ .sslDHParam }}; + ssl_dhparam {{ $cfg.SSLDHParam }}; {{ end }} - {{ if not $cfg.enableDynamicTlsRecords }} + {{ if not $cfg.EnableDynamicTLSRecords }} ssl_dyn_rec_size_lo 0; {{ end }} - {{ if .customErrors }} + {{ if .CustomErrors }} # Custom error pages proxy_intercept_errors on; {{ end }} - {{ range $errCode := $cfg.customHttpErrors }} + {{ range $errCode := $cfg.CustomHTTPErrors }} error_page {{ $errCode }} = @custom_{{ $errCode }};{{ end }} # In case of errors try the next upstream server before returning an error - proxy_next_upstream error timeout invalid_header http_502 http_503 http_504{{ if $cfg.retryNonIdempotent }} non_idempotent{{ end }}; + proxy_next_upstream error timeout invalid_header http_502 http_503 http_504{{ if $cfg.RetryNonIdempotent }} non_idempotent{{ end }}; - {{range $name, $upstream := .upstreams}} + {{range $name, $upstream := $backends}} upstream {{$upstream.Name}} { - {{ if $cfg.enableStickySessions }} + {{ if $cfg.EnableStickySessions }} sticky hash=sha1 httponly; {{ else }} least_conn; @@ -180,26 +180,26 @@ http { {{/* build all the required rate limit zones. Each annotation requires a dedicated zone */}} {{/* 1MB -> 16 thousand 64-byte states or about 8 thousand 128-byte states */}} - {{ range $zone := (buildRateLimitZones .servers) }} + {{ range $zone := (buildRateLimitZones .Servers) }} {{ $zone }} {{ end }} - {{ range $server := .servers }} + {{ range $server := .Servers }} server { - server_name {{ $server.Name }}; - listen 80{{ if $cfg.useProxyProtocol }} proxy_protocol{{ end }}; - {{ if $server.SSL }}listen 442 {{ if $cfg.useProxyProtocol }}proxy_protocol{{ end }} ssl {{ if $cfg.useHttp2 }}http2{{ end }}; + server_name {{ $server.Hostname }}; + listen 80{{ if $cfg.UseProxyProtocol }} proxy_protocol{{ end }}; + {{ if not (empty $server.SSLCertificate) }}listen 442 {{ if $cfg.UseProxyProtocol }}proxy_protocol{{ end }} ssl {{ if $cfg.UseHttp2 }}http2{{ end }}; {{/* comment PEM sha is required to detect changes in the generated configuration and force a reload */}} # PEM sha: {{ $server.SSLPemChecksum }} ssl_certificate {{ $server.SSLCertificate }}; ssl_certificate_key {{ $server.SSLCertificate }}; {{ end }} - {{ if (and $server.SSL $cfg.hsts) }} - more_set_headers "Strict-Transport-Security: max-age={{ $cfg.hstsMaxAge }}{{ if $cfg.hstsIncludeSubdomains }}; includeSubDomains{{ end }}; preload"; + {{ if (and (not (empty $server.SSLCertificate)) $cfg.HSTS) }} + more_set_headers "Strict-Transport-Security: max-age={{ $cfg.HSTSMaxAge }}{{ if $cfg.HSTSIncludeSubdomains }}; includeSubDomains{{ end }}; preload"; {{ end }} - {{ if $cfg.enableVtsStatus }}vhost_traffic_status_filter_by_set_key $geoip_country_code country::$server_name;{{ end }} + {{ if $cfg.EnableVtsStatus }}vhost_traffic_status_filter_by_set_key $geoip_country_code country::$server_name;{{ end }} {{ range $location := $server.Locations }} {{ $path := buildLocation $location }} @@ -240,7 +240,7 @@ http { auth_request {{ $authPath }}; {{ end }} - {{ if (and $server.SSL $location.Redirect.SSLRedirect) }} + {{ if (and (not (empty $server.SSLCertificate)) $location.Redirect.SSLRedirect) }} # enforce ssl on server side if ($scheme = http) { return 301 https://$host$request_uri; @@ -256,7 +256,6 @@ http { auth_basic "{{ $location.BasicDigestAuth.Realm }}"; auth_basic_user_file {{ $location.BasicDigestAuth.File }}; {{ else }} - #TODO: add nginx-http-auth-digest module auth_digest "{{ $location.BasicDigestAuth.Realm }}"; auth_digest_user_file {{ $location.BasicDigestAuth.File }}; {{ end }} @@ -300,14 +299,14 @@ http { proxy_set_header Accept-Encoding ""; {{ end }} - set $proxy_upstream_name "{{ $location.Backend.Name }}"; - {{ buildProxyPass $location }} + set $proxy_upstream_name "{{ $location.Backend }}"; + {{ buildProxyPass $backends $location }} } {{ end }} - {{ if eq $server.Name "_" }} + {{ if eq $server.Hostname "_" }} # health checks in cloud providers require the use of port 80 - location {{ $healthzURL }} { + location {{ $healthzURI }} { access_log off; return 200; } @@ -322,6 +321,7 @@ http { stub_status on; } {{ end }} + {{ template "CUSTOM_ERRORS" $cfg }} } @@ -332,15 +332,15 @@ http { # Use the port 18080 (random value just to avoid known ports) as default port for nginx. # Changing this value requires a change in: # https://github.com/kubernetes/contrib/blob/master/ingress/controllers/nginx/nginx/command.go#L104 - listen 18080 default_server reuseport backlog={{ .backlogSize }}; + listen 18080 default_server reuseport backlog={{ .BacklogSize }}; - location {{ $healthzURL }} { + location {{ $healthzURI }} { access_log off; return 200; } location /nginx_status { - {{ if $cfg.enableVtsStatus }} + {{ if $cfg.EnableVtsStatus }} vhost_traffic_status_display; vhost_traffic_status_display_format html; {{ else }} @@ -362,7 +362,7 @@ http { set $proxy_upstream_name "-"; location / { - {{ if .customErrors }} + {{ if .CustomErrors }} content_by_lua_block { openURL(503) } @@ -376,15 +376,14 @@ http { stream { # map FQDN that requires SSL passthrough map $ssl_preread_server_name $stream_upstream { - {{ range $i, $passthrough := .passthroughUpstreams }} - {{ $passthrough.Host }} {{ $passthrough.Upstream.Name }}-{{ $i }}-pt; + {{ range $i, $passthrough := .PassthrougBackends }} + {{ $passthrough.Hostname }} {{ $passthrough.Backend }}; {{ end }} # send SSL traffic to this nginx in a different port default nginx-ssl-backend; } - log_format log_stream '$remote_addr [$time_local] $protocol [$ssl_preread_server_name] [$stream_upstream] ' - '$status $bytes_sent $bytes_received $session_time'; + log_format log_stream '$remote_addr [$time_local] $protocol [$ssl_preread_server_name] [$stream_upstream] $status $bytes_sent $bytes_received $session_time'; access_log /var/log/nginx/access.log log_stream; error_log /var/log/nginx/error.log; @@ -394,56 +393,20 @@ stream { server 127.0.0.1:442; } - {{ range $i, $passthrough := .passthroughUpstreams }} - upstream {{ $passthrough.Name }}-{{ $i }}-pt { - {{ range $server := $passthrough.Endpoints }}server {{ $server.Address }}:{{ $server.Port }}; - {{ end }} - } - {{ end }} + {{ buildSSPassthroughUpstreams $backends .PassthrougBackends }} server { listen 443; - - {{ if $cfg.useProxyProtocol }}proxy_protocol on;{{ end }} - + {{ if $cfg.UseProxyProtocol }}proxy_protocol on;{{ end }} proxy_pass $stream_upstream; ssl_preread on; } -# TCP services -{{ range $i, $tcpServer := .tcpUpstreams }} - upstream tcp-{{ $tcpServer.Upstream.Name }} { - {{ range $server := $tcpServer.Upstream.Endpoints }}server {{ $server.Address }}:{{ $server.Port }}; - {{ end }} - } - - server { - listen {{ $tcpServer.Path }}; - proxy_connect_timeout {{ $tcpServer.Proxy.ConnectTimeout }}s; - proxy_timeout {{ $tcpServer.Proxy.ReadTimeout }}s; - proxy_pass tcp-{{ $tcpServer.Upstream.Name }}; - } -{{ end }} - -# UDP services -{{ range $i, $udpServer := .udpUpstreams }} - upstream udp-{{ $udpServer.Upstream.Name }} { - {{ range $server := $udpServer.Upstream.Endpoints }}server {{ $server.Address }}:{{ $server.Port }}; - {{ end }} - } - - server { - listen {{ $udpServer.Path }} udp; - proxy_timeout 10s; - proxy_responses 1; - proxy_pass udp-{{ $udpServer.Upstream.Name }}; - } -{{ end }} } {{/* definition of templates to avoid repetitions */}} {{ define "CUSTOM_ERRORS" }} - {{ range $errCode := .customHttpErrors }} + {{ range $errCode := .CustomHTTPErrors }} location @custom_{{ $errCode }} { internal; content_by_lua_block { diff --git a/controllers/nginx/test/data/config.json b/controllers/nginx/test/data/config.json new file mode 100644 index 0000000000..8f08819787 --- /dev/null +++ b/controllers/nginx/test/data/config.json @@ -0,0 +1,57259 @@ +{ + "backlogSize": 32768, + "cfg": { + "backend": { + "custom-http-errors": [404], + "proxy-buffer-size": "4k", + "proxy-connect-timeout": 5, + "proxy-read-timeout": 60, + "proxy-send-timeout": 60, + "resolver": "", + "skip-access-log-urls": ["~*health-check", "~*info"], + "ssl-redirect": true, + "upstream-fail-timeout": 0, + "upstream-max-fails": 0, + "whitelist-source-range": null + }, + "bodySize": "1m", + "enableDynamicTlsRecords": true, + "enableSpdy": false, + "enableVtsStatus": true, + "errorLogLevel": "notice", + "gzipTypes": "application/atom+xml application/javascript application/x-javascript application/json application/rss+xml application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/svg+xml image/x-icon text/css text/plain text/x-component", + "hsts": true, + "hstsIncludeSubdomains": true, + "hstsMaxAge": "15724800", + "keepAlive": 75, + "mapHashBucketSize": 64, + "maxWorkerConnections": 16384, + "proxyRealIpCidr": "0.0.0.0/0", + "retryNonIdempotent": false, + "serverNameHashBucketSize": 64, + "serverNameHashMaxSize": 16384, + "sslBufferSize": "4k", + "sslCiphers": "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA", + "sslProtocols": "TLSv1 TLSv1.1 TLSv1.2", + "sslSessionCache": true, + "sslSessionCacheSize": "10m", + "sslSessionTickets": true, + "sslSessionTimeout": "10m", + "useGzip": true, + "useHttp2": true, + "vtsStatusZoneSize": "10m", + "workerProcesses": 1 + }, + "customErrors": true, + "defResolver": "", + "healthzURI": "/healthz", + "passthrougBackends": [{ + "namespace": "default-kubernetes-443", + "hostname": "foo-898.bar.com" + }, { + "namespace": "default-echoheaders-x-80", + "hostname": "foo-997.bar.com" + }, { + "namespace": "default-kubernetes-443", + "hostname": "kubernetes.foo-bar.com" + }], + "servers": [{ + "hostname": "_", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/testpath", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": true + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }, { + "path": "/", + "isDefBackend": true, + "backend": "upstream-default-backend", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": null + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "bar.baz.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/foo", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }, { + "path": "/bar", + "isDefBackend": false, + "backend": "default-echoheaders-y-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }, { + "path": "/", + "isDefBackend": true, + "backend": "upstream-default-backend", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": null + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "default-backend.sample.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": true, + "backend": "default-echoheaders-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": null + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "external-auth-01.sample.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "https://httpbin.org/basic-auth/user/passwd", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": true + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-1.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-10.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-100.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-1000.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-101.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-102.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-103.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-104.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-105.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-106.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-107.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-108.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-109.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-11.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-110.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-111.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-112.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-113.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-114.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-115.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-116.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-117.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-118.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-119.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-12.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-120.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-121.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-122.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-123.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-124.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-125.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-126.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-127.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-128.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-129.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-13.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-130.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-131.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-132.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-133.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-134.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-135.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-136.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-137.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-138.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-139.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-14.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-140.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-141.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-142.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-143.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-144.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-145.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-146.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-147.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-148.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-149.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-15.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-150.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-151.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-152.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-153.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-154.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-155.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-156.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-157.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-158.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-159.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-16.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-160.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-161.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-162.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-163.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-164.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-165.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-166.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-167.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-168.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-169.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-17.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-170.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-171.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-172.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-173.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-174.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-175.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-176.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-177.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-178.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-179.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-18.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-180.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-181.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-182.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-183.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-184.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-185.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-186.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-187.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-188.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-189.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-19.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-190.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-191.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-192.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-193.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-194.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-195.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-196.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-197.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-198.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-199.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-2.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-20.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-200.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-201.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-202.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-203.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-204.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-205.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-206.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-207.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-208.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-209.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-21.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-210.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-211.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-212.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-213.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-214.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-215.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-216.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-217.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-218.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-219.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-22.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-220.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-221.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-222.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-223.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-224.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-225.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-226.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-227.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-228.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-229.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-23.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-230.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-231.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-232.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-233.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-234.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-235.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-236.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-237.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-238.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-239.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-24.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-240.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-241.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-242.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-243.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-244.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-245.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-246.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-247.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-248.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-249.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-25.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-250.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-251.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-252.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-253.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-254.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-255.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-256.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-257.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-258.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-259.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-26.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-260.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-261.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-262.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-263.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-264.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-265.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-266.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-267.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-268.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-269.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-27.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-270.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-271.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-272.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-273.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-274.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-275.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-276.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-277.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-278.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-279.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-28.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-280.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-281.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-282.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-283.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-284.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-285.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-286.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-287.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-288.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-289.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-29.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-290.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-291.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-292.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-293.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-294.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-295.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-296.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-297.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-298.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-299.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-3.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-30.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-300.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-301.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-302.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-303.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-304.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-305.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-306.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-307.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-308.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-309.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-31.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-310.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-311.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-312.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-313.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-314.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-315.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-316.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-317.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-318.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-319.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-32.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-320.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-321.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-322.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-323.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-324.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-325.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-326.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-327.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-328.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-329.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-33.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-330.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-331.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-332.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-333.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-334.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-335.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-336.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-337.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-338.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-339.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-34.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-340.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-341.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-342.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-343.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-344.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-345.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-346.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-347.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-348.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-349.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-35.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-350.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-351.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-352.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-353.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-354.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-355.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-356.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-357.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-358.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-359.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-36.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-360.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-361.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-362.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-363.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-364.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-365.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-366.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-367.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-368.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-369.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-37.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-370.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-371.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-372.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-373.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-374.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-375.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-376.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-377.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-378.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-379.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-38.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-380.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-381.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-382.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-383.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-384.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-385.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-386.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-387.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-388.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-389.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-39.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-390.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-391.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-392.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-393.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-394.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-395.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-396.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-397.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-398.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-399.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-4.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-40.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-400.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-401.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-402.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-403.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-404.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-405.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-406.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-407.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-408.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-409.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-41.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-410.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-411.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-412.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-413.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-414.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-415.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-416.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-417.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-418.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-419.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-42.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-420.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-421.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-422.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-423.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-424.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-425.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-426.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-427.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-428.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-429.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-43.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-430.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-431.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-432.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-433.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-434.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-435.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-436.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-437.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-438.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-439.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-44.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-440.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-441.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-442.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-443.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-444.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-445.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-446.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-447.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-448.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-449.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-45.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-450.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-451.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-452.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-453.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-454.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-455.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-456.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-457.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-458.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-459.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-46.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-460.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-461.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-462.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-463.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-464.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-465.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-466.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-467.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-468.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-469.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-47.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-470.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-471.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-472.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-473.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-474.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-475.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-476.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-477.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-478.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-479.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-48.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-480.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-481.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-482.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-483.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-484.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-485.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-486.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-487.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-488.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-489.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-49.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-490.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-491.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-492.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-493.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-494.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-495.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-496.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-497.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-498.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-499.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-5.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-50.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-500.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-501.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-502.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-503.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-504.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-505.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-506.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-507.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-508.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-509.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-51.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-510.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-511.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-512.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-513.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-514.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-515.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-516.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-517.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-518.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-519.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-52.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-520.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-521.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-522.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-523.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-524.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-525.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-526.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-527.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-528.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-529.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-53.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-530.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-531.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-532.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-533.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-534.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-535.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-536.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-537.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-538.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-539.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-54.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-540.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-541.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-542.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-543.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-544.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-545.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-546.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-547.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-548.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-549.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-55.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-550.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-551.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-552.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-553.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-554.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-555.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-556.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-557.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-558.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-559.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-56.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-560.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-561.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-562.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-563.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-564.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-565.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-566.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-567.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-568.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-569.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-57.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-570.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-571.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-572.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-573.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-574.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-575.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-576.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-577.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-578.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-579.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-58.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-580.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-581.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-582.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-583.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-584.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-585.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-586.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-587.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-588.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-589.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-59.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-590.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-591.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-592.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-593.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-594.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-595.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-596.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-597.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-598.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-599.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-6.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-60.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-600.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-601.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-602.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-603.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-604.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-605.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-606.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-607.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-608.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-609.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-61.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-610.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-611.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-612.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-613.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-614.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-615.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-616.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-617.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-618.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-619.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-62.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-620.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-621.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-622.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-623.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-624.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-625.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-626.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-627.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-628.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-629.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-63.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-630.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-631.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-632.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-633.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-634.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-635.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-636.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-637.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-638.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-639.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-64.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-640.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-641.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-642.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-643.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-644.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-645.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-646.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-647.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-648.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-649.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-65.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-650.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-651.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-652.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-653.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-654.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-655.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-656.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-657.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-658.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-659.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-66.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-660.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-661.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-662.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-663.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-664.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-665.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-666.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-667.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-668.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-669.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-67.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-670.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-671.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-672.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-673.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-674.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-675.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-676.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-677.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-678.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-679.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-68.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-680.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-681.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-682.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-683.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-684.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-685.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-686.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-687.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-688.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-689.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-69.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-690.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-691.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-692.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-693.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-694.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-695.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-696.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-697.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-698.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-699.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-7.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-70.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-700.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-701.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-702.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-703.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-704.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-705.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-706.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-707.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-708.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-709.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-71.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-710.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-711.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-712.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-713.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-714.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-715.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-716.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-717.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-718.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-719.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-72.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-720.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-721.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-722.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-723.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-724.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-725.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-726.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-727.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-728.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-729.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-73.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-730.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-731.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-732.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-733.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-734.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-735.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-736.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-737.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-738.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-739.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-74.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-740.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-741.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-742.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-743.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-744.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-745.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-746.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-747.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-748.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-749.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-75.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-750.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-751.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-752.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-753.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-754.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-755.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-756.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-757.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-758.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-759.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-76.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-760.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-761.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-762.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-763.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-764.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-765.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-766.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-767.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-768.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-769.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-77.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-770.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-771.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-772.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-773.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-774.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-775.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-776.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-777.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-778.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-779.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-78.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-780.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-781.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-782.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-783.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-784.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-785.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-786.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-787.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-788.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-789.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-79.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-790.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-791.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-792.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-793.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-794.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-795.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-796.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-797.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-798.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-799.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-8.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-80.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-800.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-801.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-802.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-803.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-804.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-805.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-806.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-807.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-808.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-809.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-81.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-810.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-811.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-812.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-813.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-814.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-815.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-816.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-817.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-818.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-819.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-82.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-820.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-821.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-822.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-823.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-824.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-825.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-826.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-827.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-828.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-829.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-83.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-830.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-831.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-832.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-833.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-834.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-835.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-836.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-837.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-838.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-839.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-84.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-840.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-841.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-842.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-843.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-844.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-845.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-846.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-847.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-848.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-849.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-85.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-850.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-851.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-852.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-853.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-854.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-855.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-856.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-857.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-858.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-859.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-86.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-860.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-861.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-862.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-863.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-864.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-865.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-866.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-867.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-868.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-869.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-87.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-870.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-871.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-872.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-873.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-874.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-875.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-876.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-877.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-878.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-879.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-88.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-880.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-881.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-882.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-883.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-884.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-885.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-886.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-887.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-888.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-889.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-89.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-890.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-891.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-892.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-893.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-894.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-895.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-896.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-897.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-898.bar.com", + "sslPassthrough": true, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-kubernetes-443", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": true + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-899.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-9.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-90.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-900.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-901.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-902.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-903.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-904.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-905.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-906.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-907.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-908.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-909.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-91.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-910.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-911.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-912.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-913.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-914.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-915.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-916.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-917.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-918.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-919.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-92.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-920.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-921.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-922.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-923.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-924.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-925.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-926.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-927.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-928.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-929.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-93.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-930.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-931.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-932.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-933.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-934.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-935.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-936.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-937.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-938.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-939.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-94.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-940.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-941.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-942.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-943.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-944.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-945.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-946.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-947.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-948.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-949.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-95.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-950.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-951.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-952.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-953.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-954.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-955.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-956.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-957.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-958.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-959.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-96.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-960.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-961.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-962.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-963.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-964.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-965.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-966.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-967.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-968.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-969.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-97.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-970.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-971.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-972.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-973.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-974.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-975.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-976.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-977.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-978.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-979.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-98.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-980.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-981.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-982.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-983.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-984.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-985.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-986.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-987.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-988.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-989.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-99.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-990.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-991.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-992.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": true + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "default/aledbf-ca-secret", + "certFilename": "/ingress-controller/ssl/default-aledbf-ca-secret.pem", + "keyFilename": "", + "caFilename": "/ingress-controller/ssl/ca-default-aledbf-ca-secret.pem", + "pemSha": "69d055bd017208111377c971ba5ee0987fecee65" + } + }] + }, { + "hostname": "foo-993.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-994.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-995.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-996.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-997.bar.com", + "sslPassthrough": true, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": true + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo-998.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "https://httpbin.org/basic-auth/user/passwd", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": true + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/foo", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }, { + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo2.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-xtp-echo-port", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": true + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foo3.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-xtp-echo-port", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "foos.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": true + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "jenkins.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/jenkins", + "isDefBackend": false, + "backend": "default-jenkins-8080", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "default_jenkins_conn", + "limit": 2, + "burst": 10, + "sharedSize": 5 + }, + "rps": { + "name": "default_jenkins_rps", + "limit": 0, + "burst": 10, + "sharedSize": 5 + } + }, + "redirect": { + "target": "/", + "addBaseUrl": true, + "sslRedirect": true + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }, { + "path": "/", + "isDefBackend": true, + "backend": "upstream-default-backend", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": null + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "kubernetes.foo-bar.com", + "sslPassthrough": true, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-kubernetes-443", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": true + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "no-root.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/api", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }, { + "path": "/", + "isDefBackend": true, + "backend": "upstream-default-backend", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": null + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "rewrite.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/something", + "isDefBackend": false, + "backend": "default-echoheaders-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "/", + "addBaseUrl": false, + "sslRedirect": true + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }, { + "path": "/", + "isDefBackend": true, + "backend": "upstream-default-backend", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": null + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "whitelist.bar.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": true + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }, { + "hostname": "with-root.com", + "sslPassthrough": false, + "sslCertificate": "", + "sslPemChecksum": "", + "locations": [{ + "path": "/", + "isDefBackend": false, + "backend": "default-echoheaders-x-80", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": [] + }, + "proxy": { + "conectTimeout": 5, + "sendTimeout": 60, + "readTimeout": 60, + "bufferSize": "4k" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }] + }], + "sslDHParam": "", + "tcpBackends": [{ + "path": "2222", + "isDefBackend": false, + "backend": "default-echoheaders-2222", + "basicDigestAuth": { + "type": "", + "realm": "", + "file": "", + "secured": false + }, + "externalAuth": { + "url": "", + "method": "", + "sendBody": false + }, + "rateLimit": { + "connections": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + }, + "rps": { + "name": "", + "limit": 0, + "burst": 0, + "sharedSize": 0 + } + }, + "redirect": { + "target": "", + "addBaseUrl": false, + "sslRedirect": false + }, + "whitelist": { + "cidr": null + }, + "proxy": { + "conectTimeout": 0, + "sendTimeout": 0, + "readTimeout": 0, + "bufferSize": "" + }, + "certificateAuth": { + "secret": "", + "certFilename": "", + "keyFilename": "", + "caFilename": "", + "pemSha": "" + } + }], + "udpBackends": [], + "backends": [{ + "name": "default-echoheaders-80", + "secure": false, + "endpoints": [{ + "address": "10.2.3.2", + "port": "8080", + "maxFails": 0, + "failTimeout": 0 + }, { + "address": "10.2.3.5", + "port": "8080", + "maxFails": 0, + "failTimeout": 0 + }] + }, { + "name": "default-echoheaders-x-80", + "secure": false, + "endpoints": [{ + "address": "10.2.3.4", + "port": "8080", + "maxFails": 0, + "failTimeout": 0 + }] + }, { + "name": "default-echoheaders-xtp-echo-port", + "secure": false, + "endpoints": [{ + "address": "127.0.0.1", + "port": "8181", + "maxFails": 0, + "failTimeout": 0 + }] + }, { + "name": "default-echoheaders-y-80", + "secure": false, + "endpoints": [{ + "address": "10.2.3.4", + "port": "8080", + "maxFails": 0, + "failTimeout": 0 + }] + }, { + "name": "default-jenkins-8080", + "secure": false, + "endpoints": [{ + "address": "127.0.0.1", + "port": "8181", + "maxFails": 0, + "failTimeout": 0 + }] + }, { + "name": "default-kubernetes-443", + "secure": false, + "endpoints": [{ + "address": "172.17.4.99", + "port": "443", + "maxFails": 0, + "failTimeout": 0 + }] + }, { + "name": "upstream-default-backend", + "secure": false, + "endpoints": [{ + "address": "10.2.3.11", + "port": "8080", + "maxFails": 0, + "failTimeout": 0 + }] + }] +} \ No newline at end of file diff --git a/core/pkg/ingress/annotations/auth/main.go b/core/pkg/ingress/annotations/auth/main.go index 963dc35eb6..70acde2e1d 100644 --- a/core/pkg/ingress/annotations/auth/main.go +++ b/core/pkg/ingress/annotations/auth/main.go @@ -23,10 +23,10 @@ import ( "os" "regexp" - "k8s.io/ingress/core/pkg/ingress/annotations/parser" - "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/apis/extensions" + + "k8s.io/ingress/core/pkg/ingress/annotations/parser" ) const ( @@ -59,10 +59,10 @@ var ( // BasicDigest returns authentication configuration for an Ingress rule type BasicDigest struct { - Type string - Realm string - File string - Secured bool + Type string `json:"type"` + Realm string `json:"realm"` + File string `json:"file"` + Secured bool `json:"secured"` } // ParseAnnotations parses the annotations contained in the ingress diff --git a/core/pkg/ingress/annotations/authreq/main.go b/core/pkg/ingress/annotations/authreq/main.go index efa0d79043..3e5f33c7c0 100644 --- a/core/pkg/ingress/annotations/authreq/main.go +++ b/core/pkg/ingress/annotations/authreq/main.go @@ -21,8 +21,9 @@ import ( "net/url" "strings" - "k8s.io/ingress/core/pkg/ingress/annotations/parser" "k8s.io/kubernetes/pkg/apis/extensions" + + "k8s.io/ingress/core/pkg/ingress/annotations/parser" ) const ( @@ -34,9 +35,9 @@ const ( // External returns external authentication configuration for an Ingress rule type External struct { - URL string - Method string - SendBody bool + URL string `json:"url"` + Method string `json:"method"` + SendBody bool `json:"sendBody"` } var ( diff --git a/core/pkg/ingress/annotations/authtls/main.go b/core/pkg/ingress/annotations/authtls/main.go index b515c37744..3d80e0deb8 100644 --- a/core/pkg/ingress/annotations/authtls/main.go +++ b/core/pkg/ingress/annotations/authtls/main.go @@ -19,10 +19,10 @@ package authtls import ( "fmt" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/ingress/core/pkg/ingress/annotations/parser" "k8s.io/ingress/core/pkg/k8s" - - "k8s.io/kubernetes/pkg/apis/extensions" ) const ( @@ -32,11 +32,11 @@ const ( // SSLCert returns external authentication configuration for an Ingress rule type SSLCert struct { - Secret string - CertFileName string - KeyFileName string - CAFileName string - PemSHA string + Secret string `json:"secret"` + CertFileName string `json:"certFilename"` + KeyFileName string `json:"keyFilename"` + CAFileName string `json:"caFilename"` + PemSHA string `json:"pemSha"` } // ParseAnnotations parses the annotations contained in the ingress diff --git a/core/pkg/ingress/annotations/cors/main.go b/core/pkg/ingress/annotations/cors/main.go index 4208965056..53d9cca6df 100644 --- a/core/pkg/ingress/annotations/cors/main.go +++ b/core/pkg/ingress/annotations/cors/main.go @@ -17,9 +17,9 @@ limitations under the License. package cors import ( - "k8s.io/ingress/core/pkg/ingress/annotations/parser" - "k8s.io/kubernetes/pkg/apis/extensions" + + "k8s.io/ingress/core/pkg/ingress/annotations/parser" ) const ( diff --git a/core/pkg/ingress/annotations/healthcheck/main.go b/core/pkg/ingress/annotations/healthcheck/main.go index 344db3c6da..9dfc2050ac 100644 --- a/core/pkg/ingress/annotations/healthcheck/main.go +++ b/core/pkg/ingress/annotations/healthcheck/main.go @@ -31,8 +31,8 @@ const ( // Upstream returns the URL and method to use check the status of // the upstream server/s type Upstream struct { - MaxFails int - FailTimeout int + MaxFails int `json:"maxFails"` + FailTimeout int `json:"failTimeout"` } // ParseAnnotations parses the annotations contained in the ingress diff --git a/core/pkg/ingress/annotations/ipwhitelist/main.go b/core/pkg/ingress/annotations/ipwhitelist/main.go index f3ff0fe21a..14f3ce00ab 100644 --- a/core/pkg/ingress/annotations/ipwhitelist/main.go +++ b/core/pkg/ingress/annotations/ipwhitelist/main.go @@ -20,11 +20,11 @@ import ( "errors" "strings" - "k8s.io/ingress/core/pkg/ingress/annotations/parser" - "k8s.io/ingress/core/pkg/ingress/defaults" - "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/util/net/sets" + + "k8s.io/ingress/core/pkg/ingress/annotations/parser" + "k8s.io/ingress/core/pkg/ingress/defaults" ) const ( @@ -39,7 +39,7 @@ var ( // SourceRange returns the CIDR type SourceRange struct { - CIDR []string + CIDR []string `json:"cidr"` } // ParseAnnotations parses the annotations contained in the ingress diff --git a/core/pkg/ingress/annotations/proxy/main.go b/core/pkg/ingress/annotations/proxy/main.go index 321a46652a..d749f1849f 100644 --- a/core/pkg/ingress/annotations/proxy/main.go +++ b/core/pkg/ingress/annotations/proxy/main.go @@ -32,10 +32,10 @@ const ( // Configuration returns the proxy timeout to use in the upstream server/s type Configuration struct { - ConnectTimeout int - SendTimeout int - ReadTimeout int - BufferSize string + ConnectTimeout int `json:"conectTimeout"` + SendTimeout int `json:"sendTimeout"` + ReadTimeout int `json:"readTimeout"` + BufferSize string `json:"bufferSize"` } // ParseAnnotations parses the annotations contained in the ingress diff --git a/core/pkg/ingress/annotations/ratelimit/main.go b/core/pkg/ingress/annotations/ratelimit/main.go index c084d76e83..774bf6e074 100644 --- a/core/pkg/ingress/annotations/ratelimit/main.go +++ b/core/pkg/ingress/annotations/ratelimit/main.go @@ -20,9 +20,9 @@ import ( "errors" "fmt" - "k8s.io/ingress/core/pkg/ingress/annotations/parser" - "k8s.io/kubernetes/pkg/apis/extensions" + + "k8s.io/ingress/core/pkg/ingress/annotations/parser" ) const ( @@ -48,19 +48,19 @@ var ( // Note: Is possible to specify both limits type RateLimit struct { // Connections indicates a limit with the number of connections per IP address - Connections Zone + Connections Zone `json:"connections"` // RPS indicates a limit with the number of connections per second - RPS Zone + RPS Zone `json:"rps"` } // Zone returns information about the NGINX rate limit (limit_req_zone) // http://nginx.org/en/docs/http/ngx_http_limit_req_module.html#limit_req_zone type Zone struct { - Name string - Limit int - Burst int + Name string `json:"name"` + Limit int `json:"limit"` + Burst int `json:"burst"` // SharedSize amount of shared memory for the zone - SharedSize int + SharedSize int `json:"sharedSize"` } // ParseAnnotations parses the annotations contained in the ingress diff --git a/core/pkg/ingress/annotations/rewrite/main.go b/core/pkg/ingress/annotations/rewrite/main.go index 6dfce3d63e..33ff7bcad1 100644 --- a/core/pkg/ingress/annotations/rewrite/main.go +++ b/core/pkg/ingress/annotations/rewrite/main.go @@ -19,10 +19,10 @@ package rewrite import ( "errors" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/ingress/core/pkg/ingress/annotations/parser" "k8s.io/ingress/core/pkg/ingress/defaults" - - "k8s.io/kubernetes/pkg/apis/extensions" ) const ( @@ -34,12 +34,12 @@ const ( // Redirect describes the per location redirect config type Redirect struct { // Target URI where the traffic must be redirected - Target string + Target string `json:"target"` // AddBaseURL indicates if is required to add a base tag in the head // of the responses from the upstream servers - AddBaseURL bool + AddBaseURL bool `json:"addBaseUrl"` // SSLRedirect indicates if the location section is accessible SSL only - SSLRedirect bool + SSLRedirect bool `json:"sslRedirect"` } // ParseAnnotations parses the annotations contained in the ingress diff --git a/core/pkg/ingress/annotations/secureupstream/main.go b/core/pkg/ingress/annotations/secureupstream/main.go index f80f36c89b..32240df32e 100644 --- a/core/pkg/ingress/annotations/secureupstream/main.go +++ b/core/pkg/ingress/annotations/secureupstream/main.go @@ -17,9 +17,9 @@ limitations under the License. package secureupstream import ( - "k8s.io/ingress/core/pkg/ingress/annotations/parser" - "k8s.io/kubernetes/pkg/apis/extensions" + + "k8s.io/ingress/core/pkg/ingress/annotations/parser" ) const ( diff --git a/core/pkg/ingress/annotations/sslpassthrough/main.go b/core/pkg/ingress/annotations/sslpassthrough/main.go index b4d70973f5..765cca227d 100644 --- a/core/pkg/ingress/annotations/sslpassthrough/main.go +++ b/core/pkg/ingress/annotations/sslpassthrough/main.go @@ -19,10 +19,10 @@ package sslpassthrough import ( "fmt" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/ingress/core/pkg/ingress/annotations/parser" "k8s.io/ingress/core/pkg/ingress/defaults" - - "k8s.io/kubernetes/pkg/apis/extensions" ) const ( diff --git a/core/pkg/ingress/controller/backend_ssl.go b/core/pkg/ingress/controller/backend_ssl.go index 30efef5c46..d6f2f0c548 100644 --- a/core/pkg/ingress/controller/backend_ssl.go +++ b/core/pkg/ingress/controller/backend_ssl.go @@ -21,11 +21,12 @@ import ( "strings" "time" + "github.com/golang/glog" + "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/client/cache" - "github.com/golang/glog" "k8s.io/ingress/core/pkg/ingress" "k8s.io/ingress/core/pkg/ingress/annotations/parser" ssl "k8s.io/ingress/core/pkg/net/ssl" diff --git a/core/pkg/ingress/controller/controller.go b/core/pkg/ingress/controller/controller.go index ce4fd07504..0d349a3d9a 100644 --- a/core/pkg/ingress/controller/controller.go +++ b/core/pkg/ingress/controller/controller.go @@ -301,7 +301,7 @@ func (ic GenericController) Check(_ *http.Request) error { } // Info returns information about the backend -func (ic GenericController) Info() string { +func (ic GenericController) Info() *ingress.BackendInfo { return ic.cfg.Backend.Info() } @@ -368,31 +368,25 @@ func (ic *GenericController) sync(key interface{}) error { continue } passUpstreams = append(passUpstreams, &ingress.SSLPassthroughBackend{ - Upstream: loc.Backend, - Host: server.Name, + Backend: loc.Backend, + Hostname: server.Hostname, }) break } } data, err := ic.cfg.Backend.OnUpdate(cfg, ingress.Configuration{ - HealthzURL: ic.cfg.DefaultHealthzURL, - Upstreams: upstreams, - Servers: servers, - TCPEndpoints: ic.getTCPServices(), - UPDEndpoints: ic.getUDPServices(), - PassthroughUpstreams: passUpstreams, + Backends: upstreams, + Servers: servers, + TCPEndpoints: ic.getTCPServices(), + UPDEndpoints: ic.getUDPServices(), + PassthroughBackends: passUpstreams, }) if err != nil { return err } - if !ic.cfg.Backend.IsReloadRequired(data) { - return nil - } - - glog.Infof("reloading ingress backend...") - out, err := ic.cfg.Backend.Restart(data) + out, err := ic.cfg.Backend.Reload(data) if err != nil { incReloadErrorCount() glog.Errorf("unexpected failure restarting the backend: \n%v", string(out)) @@ -517,11 +511,8 @@ func (ic *GenericController) getStreamServices(data map[string]string, proto api } svcs = append(svcs, &ingress.Location{ - Path: k, - Upstream: ingress.Backend{ - Name: fmt.Sprintf("%v-%v-%v", svcNs, svcName, port), - Endpoints: endps, - }, + Path: k, + Backend: fmt.Sprintf("%v-%v-%v", svcNs, svcName, port), }) } @@ -579,7 +570,7 @@ func (ic *GenericController) getBackendServers() ([]*ingress.Backend, []*ingress upstreams := ic.createUpstreams(ings) servers := ic.createServers(ings, upstreams) - upsDefaults := ic.cfg.Backend.UpstreamDefaults() + upsDefaults := ic.cfg.Backend.BackendDefaults() for _, ingIf := range ings { ing := ingIf.(*extensions.Ingress) @@ -596,11 +587,6 @@ func (ic *GenericController) getBackendServers() ([]*ingress.Backend, []*ingress glog.V(5).Infof("error reading rate limit annotation in Ingress %v/%v: %v", ing.GetNamespace(), ing.GetName(), err) } - secUpstream, err := secureupstream.ParseAnnotations(ing) - if err != nil { - glog.V(5).Infof("error reading secure upstream in Ingress %v/%v: %v", ing.GetNamespace(), ing.GetName(), err) - } - locRew, err := rewrite.ParseAnnotations(upsDefaults, ing) if err != nil { glog.V(5).Infof("error parsing rewrite annotations for Ingress rule %v/%v: %v", ing.GetNamespace(), ing.GetName(), err) @@ -666,7 +652,7 @@ func (ic *GenericController) getBackendServers() ([]*ingress.Backend, []*ingress len(ing.Spec.TLS) == 0 && host != defServerName { glog.V(3).Infof("ingress rule %v/%v does not contains HTTP or TLS rules. using default backend", ing.Namespace, ing.Name) - server.Locations[0].Upstream = *defBackend + server.Locations[0].Backend = defBackend.Name continue } @@ -690,19 +676,19 @@ func (ic *GenericController) getBackendServers() ([]*ingress.Backend, []*ingress addLoc = false if !loc.IsDefBackend { - glog.V(3).Infof("avoiding replacement of ingress rule %v/%v location %v upstream %v (%v)", ing.Namespace, ing.Name, loc.Path, ups.Name, loc.Backend.Name) + glog.V(3).Infof("avoiding replacement of ingress rule %v/%v location %v upstream %v (%v)", ing.Namespace, ing.Name, loc.Path, ups.Name, loc.Backend) break } - glog.V(3).Infof("replacing ingress rule %v/%v location %v upstream %v (%v)", ing.Namespace, ing.Name, loc.Path, ups.Name, loc.Backend.Name) - loc.Backend = *ups + glog.V(3).Infof("replacing ingress rule %v/%v location %v upstream %v (%v)", ing.Namespace, ing.Name, loc.Path, ups.Name, loc.Backend) + loc.Backend = ups.Name loc.IsDefBackend = false loc.BasicDigestAuth = *nginxAuth loc.RateLimit = *rl loc.Redirect = *locRew - loc.SecureUpstream = secUpstream + //loc.SecureUpstream = secUpstream loc.Whitelist = *wl - loc.Backend = *ups + loc.Backend = ups.Name loc.EnableCORS = eCORS loc.ExternalAuth = ra loc.Proxy = *prx @@ -712,15 +698,15 @@ func (ic *GenericController) getBackendServers() ([]*ingress.Backend, []*ingress } // is a new location if addLoc { - glog.V(3).Infof("adding location %v in ingress rule %v/%v upstream", nginxPath, ing.Namespace, ing.Name, ups.Name) + glog.V(3).Infof("adding location %v in ingress rule %v/%v upstream %v", nginxPath, ing.Namespace, ing.Name, ups.Name) server.Locations = append(server.Locations, &ingress.Location{ Path: nginxPath, - Upstream: *ups, + Backend: ups.Name, IsDefBackend: false, BasicDigestAuth: *nginxAuth, RateLimit: *rl, Redirect: *locRew, - SecureUpstream: secUpstream, + //SecureUpstream: secUpstream, Whitelist: *wl, EnableCORS: eCORS, ExternalAuth: ra, @@ -776,10 +762,15 @@ func (ic *GenericController) createUpstreams(data []interface{}) map[string]*ing upstreams := make(map[string]*ingress.Backend) upstreams[defUpstreamName] = ic.getDefaultUpstream() - upsDefaults := ic.cfg.Backend.UpstreamDefaults() + upsDefaults := ic.cfg.Backend.BackendDefaults() for _, ingIf := range data { ing := ingIf.(*extensions.Ingress) + secUpstream, err := secureupstream.ParseAnnotations(ing) + if err != nil { + glog.V(5).Infof("error reading secure upstream in Ingress %v/%v: %v", ing.GetNamespace(), ing.GetName(), err) + } + hz := healthcheck.ParseAnnotations(upsDefaults, ing) var defBackend string @@ -817,7 +808,9 @@ func (ic *GenericController) createUpstreams(data []interface{}) map[string]*ing glog.V(3).Infof("creating upstream %v", name) upstreams[name] = newUpstream(name) - + if !upstreams[name].Secure { + upstreams[name].Secure = secUpstream + } svcKey := fmt.Sprintf("%v/%v", ing.GetNamespace(), path.Backend.ServiceName) endp, err := ic.serviceEndpoints(svcKey, path.Backend.ServicePort.String(), hz) if err != nil { @@ -871,18 +864,18 @@ func (ic *GenericController) serviceEndpoints(svcKey, backendPort string, func (ic *GenericController) createServers(data []interface{}, upstreams map[string]*ingress.Backend) map[string]*ingress.Server { servers := make(map[string]*ingress.Server) - ngxProxy := *proxy.ParseAnnotations(ic.cfg.Backend.UpstreamDefaults(), nil) + ngxProxy := *proxy.ParseAnnotations(ic.cfg.Backend.BackendDefaults(), nil) - upsDefaults := ic.cfg.Backend.UpstreamDefaults() + upsDefaults := ic.cfg.Backend.BackendDefaults() // default server servers[defServerName] = &ingress.Server{ - Name: defServerName, + Hostname: defServerName, Locations: []*ingress.Location{ { Path: rootLocation, IsDefBackend: true, - Upstream: *ic.getDefaultUpstream(), + Backend: ic.getDefaultUpstream().Name, Proxy: ngxProxy, }, }} @@ -906,12 +899,12 @@ func (ic *GenericController) createServers(data []interface{}, upstreams map[str continue } servers[host] = &ingress.Server{ - Name: host, + Hostname: host, Locations: []*ingress.Location{ { Path: rootLocation, IsDefBackend: true, - Upstream: *ic.getDefaultUpstream(), + Backend: ic.getDefaultUpstream().Name, Proxy: ngxProxy, }, }, SSLPassthrough: sslpt} @@ -929,15 +922,13 @@ func (ic *GenericController) createServers(data []interface{}, upstreams map[str } // only add certificate if the server does not have one previously configured - if len(ing.Spec.TLS) > 0 && !servers[host].SSL { + if len(ing.Spec.TLS) > 0 && servers[host].SSLCertificate != "" { key := fmt.Sprintf("%v/%v", ing.Namespace, ing.Spec.TLS[0].SecretName) bc, exists := ic.sslCertTracker.Get(key) if exists { cert := bc.(*ingress.SSLCert) if isHostValid(host, cert) { - servers[host].SSL = true servers[host].SSLCertificate = cert.PemFileName - //servers[host].SSLCertificateKey = cert.PemFileName servers[host].SSLPemChecksum = cert.PemSHA } } @@ -950,7 +941,7 @@ func (ic *GenericController) createServers(data []interface{}, upstreams map[str ic.recorder.Eventf(ing, api.EventTypeWarning, "MAPPING", "error: rules with Spec.Backend are allowed only with hostnames") continue } - servers[host].Locations[0].Upstream = *backendUpstream + servers[host].Locations[0].Backend = backendUpstream.Name } } } @@ -1050,7 +1041,6 @@ func (ic GenericController) Stop() error { // Start starts the Ingress controller. func (ic GenericController) Start() { glog.Infof("starting Ingress controller") - go ic.cfg.Backend.Start() go ic.ingController.Run(ic.stopCh) go ic.endpController.Run(ic.stopCh) diff --git a/core/pkg/ingress/controller/launch.go b/core/pkg/ingress/controller/launch.go index 7d4883a3c7..41dbaf284f 100644 --- a/core/pkg/ingress/controller/launch.go +++ b/core/pkg/ingress/controller/launch.go @@ -1,6 +1,7 @@ package controller import ( + "encoding/json" "flag" "fmt" "net/http" @@ -12,15 +13,15 @@ import ( "github.com/golang/glog" "github.com/spf13/pflag" - "k8s.io/ingress/core/pkg/ingress" - "k8s.io/ingress/core/pkg/k8s" - "github.com/prometheus/client_golang/prometheus" "k8s.io/kubernetes/pkg/api" clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" "k8s.io/kubernetes/pkg/client/restclient" "k8s.io/kubernetes/pkg/healthz" kubectl_util "k8s.io/kubernetes/pkg/kubectl/cmd/util" + + "k8s.io/ingress/core/pkg/ingress" + "k8s.io/ingress/core/pkg/k8s" ) // NewIngressController returns a configured Ingress controller @@ -160,7 +161,8 @@ func registerHandlers(enableProfiling bool, port int, ic *GenericController) { mux.HandleFunc("/build", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, ic.Info()) + b, _ := json.Marshal(ic.Info()) + w.Write(b) }) mux.HandleFunc("/stop", func(w http.ResponseWriter, r *http.Request) { diff --git a/core/pkg/ingress/controller/named_port.go b/core/pkg/ingress/controller/named_port.go index 1b9a09dc4b..c1cdeb6e22 100644 --- a/core/pkg/ingress/controller/named_port.go +++ b/core/pkg/ingress/controller/named_port.go @@ -24,11 +24,11 @@ import ( "github.com/golang/glog" - "k8s.io/ingress/core/pkg/ingress/annotations/service" - "k8s.io/kubernetes/pkg/api" podutil "k8s.io/kubernetes/pkg/api/pod" "k8s.io/kubernetes/pkg/labels" + + "k8s.io/ingress/core/pkg/ingress/annotations/service" ) // checkSvcForUpdate verifies if one of the running pods for a service contains diff --git a/core/pkg/ingress/controller/util.go b/core/pkg/ingress/controller/util.go index 3d5c7619d3..c3e4f249ca 100644 --- a/core/pkg/ingress/controller/util.go +++ b/core/pkg/ingress/controller/util.go @@ -19,10 +19,10 @@ package controller import ( "strings" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/ingress/core/pkg/ingress" "k8s.io/ingress/core/pkg/ingress/annotations/parser" - - "k8s.io/kubernetes/pkg/apis/extensions" ) // newDefaultServer return an BackendServer to be use as default server that returns 503. @@ -33,7 +33,7 @@ func newDefaultServer() ingress.Endpoint { // newUpstream creates an upstream without servers. func newUpstream(name string) *ingress.Backend { return &ingress.Backend{ - Name: name, + Name: name, Endpoints: []ingress.Endpoint{}, } } diff --git a/core/pkg/ingress/doc.go b/core/pkg/ingress/doc.go new file mode 100644 index 0000000000..54ddb718f9 --- /dev/null +++ b/core/pkg/ingress/doc.go @@ -0,0 +1,63 @@ +/* +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 ingress + +// This package contains the interface is required to implement to build an Ingress controller +// A dummy implementation could be +// +// func main() { +// dc := newDummyController() +// controller.NewIngressController(dc) +// glog.Infof("shutting down Ingress controller...") +// } +// +//where newDummyController returns and implementation of the Controller interface: +// +// func newDummyController() ingress.Controller { +// return &DummyController{} +// } +// +// type DummyController struct { +// } +// +// func (dc DummyController) Reload(data []byte) ([]byte, error) { +// err := ioutil.WriteFile("/arbitrary-path", data, 0644) +// if err != nil { +// return nil, err +// } +// +// return exec.Command("some command", "--reload").CombinedOutput() +// } +// +// func (dc DummyController) Test(file string) *exec.Cmd { +// return exec.Command("some command", "--config-file", file) +// } +// +// func (dc DummyController) OnUpdate(*api.ConfigMap, Configuration) ([]byte, error) { +// return []byte(``) +// } +// +// func (dc DummyController) BackendDefaults() defaults.Backend { +// return ingress.NewStandardDefaults() +// } +// +// func (dc DummyController) Info() *BackendInfo { +// Name: "dummy", +// Release: "0.0.0", +// Build: "git-00000000", +// Repository: "git://foo.bar.com", +// } diff --git a/core/pkg/ingress/sort_ingress.go b/core/pkg/ingress/sort_ingress.go new file mode 100644 index 0000000000..cc5f2d76d8 --- /dev/null +++ b/core/pkg/ingress/sort_ingress.go @@ -0,0 +1,85 @@ +/* +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 ingress + +import ( + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" +) + +// BackendByNameServers sorts upstreams by name +type BackendByNameServers []*Backend + +func (c BackendByNameServers) Len() int { return len(c) } +func (c BackendByNameServers) Swap(i, j int) { c[i], c[j] = c[j], c[i] } +func (c BackendByNameServers) Less(i, j int) bool { + + return c[i].Name < c[j].Name +} + +// EndpointByAddrPort sorts endpoints by address and port +type EndpointByAddrPort []Endpoint + +func (c EndpointByAddrPort) Len() int { return len(c) } +func (c EndpointByAddrPort) Swap(i, j int) { c[i], c[j] = c[j], c[i] } +func (c EndpointByAddrPort) Less(i, j int) bool { + iName := c[i].Address + jName := c[j].Address + if iName != jName { + return iName < jName + } + + iU := c[i].Port + jU := c[j].Port + return iU < jU +} + +// ServerByName sorts servers by name +type ServerByName []*Server + +func (c ServerByName) Len() int { return len(c) } +func (c ServerByName) Swap(i, j int) { c[i], c[j] = c[j], c[i] } +func (c ServerByName) Less(i, j int) bool { + return c[i].Hostname < c[j].Hostname +} + +// LocationByPath sorts location by path in descending order +// Location / is the last one +type LocationByPath []*Location + +func (c LocationByPath) Len() int { return len(c) } +func (c LocationByPath) Swap(i, j int) { c[i], c[j] = c[j], c[i] } +func (c LocationByPath) Less(i, j int) bool { + return c[i].Path > c[j].Path +} + +// SSLCert describes a SSL certificate to be used in a server +type SSLCert struct { + api.ObjectMeta `json:"metadata,omitempty"` + // CAFileName contains the path to the file with the root certificate + CAFileName string `json:"caFileName"` + // PemFileName contains the path to the file with the certificate and key concatenated + PemFileName string `json:"pemFileName"` + // PemSHA contains the sha1 of the pem file. + // This is used to detect changes in the secret that contains the certificates + PemSHA string `json:"pemSha"` + // CN contains all the common names defined in the SSL certificate + CN []string `json:"cn"` +} + +// GetObjectKind implements the ObjectKind interface as a noop +func (s SSLCert) GetObjectKind() unversioned.ObjectKind { return unversioned.EmptyObjectKind } diff --git a/core/pkg/ingress/status/status.go b/core/pkg/ingress/status/status.go index f454beb69d..3a00aa7630 100644 --- a/core/pkg/ingress/status/status.go +++ b/core/pkg/ingress/status/status.go @@ -23,17 +23,17 @@ import ( "github.com/golang/glog" - cache_store "k8s.io/ingress/core/pkg/cache" - "k8s.io/ingress/core/pkg/k8s" - strings "k8s.io/ingress/core/pkg/strings" - "k8s.io/ingress/core/pkg/task" - "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/apis/extensions" clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" "k8s.io/kubernetes/pkg/client/leaderelection" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/util/wait" + + cache_store "k8s.io/ingress/core/pkg/cache" + "k8s.io/ingress/core/pkg/k8s" + strings "k8s.io/ingress/core/pkg/strings" + "k8s.io/ingress/core/pkg/task" ) const ( diff --git a/core/pkg/ingress/types.go b/core/pkg/ingress/types.go new file mode 100644 index 0000000000..dd490ad701 --- /dev/null +++ b/core/pkg/ingress/types.go @@ -0,0 +1,243 @@ +/* +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 ingress + +import ( + "os/exec" + + "k8s.io/kubernetes/pkg/api" + + "k8s.io/ingress/core/pkg/ingress/annotations/auth" + "k8s.io/ingress/core/pkg/ingress/annotations/authreq" + "k8s.io/ingress/core/pkg/ingress/annotations/authtls" + "k8s.io/ingress/core/pkg/ingress/annotations/ipwhitelist" + "k8s.io/ingress/core/pkg/ingress/annotations/proxy" + "k8s.io/ingress/core/pkg/ingress/annotations/ratelimit" + "k8s.io/ingress/core/pkg/ingress/annotations/rewrite" + "k8s.io/ingress/core/pkg/ingress/defaults" +) + +var ( + // DefaultSSLDirectory defines the location where the SSL certificates will be generated + // This directory contains all the SSL certificates that are specified in Ingress rules. + // The name of each file is -.pem. The content is the concatenated + // certificate and key. + DefaultSSLDirectory = "/ingress-controller/ssl" +) + +// Controller holds the methods to handle an Ingress backend +// TODO (#18): Make sure this is sufficiently supportive of other backends. +type Controller interface { + // Reload takes a byte array representing the new loadbalancer configuration, + // and returns a byte array containing any output/errors from the backend. + // Before returning the backend must load the configuration in the given array + // into the loadbalancer and restart it, or fail with an error and message string. + // If reloading fails, there should be not change in the running configuration or + // the given byte array. + Reload(data []byte) ([]byte, error) + // Tests returns the commands to execute that verifies if the configuration file is valid + // Example: nginx -t -c + Test(file string) *exec.Cmd + // OnUpdate callback invoked from the sync queue https://k8s.io/ingress/core/blob/master/pkg/ingress/controller/controller.go#L387 + // when an update occurs. This is executed frequently because Ingress + // controllers watches changes in: + // - Ingresses: main work + // - Secrets: referenced from Ingress rules with TLS configured + // - ConfigMaps: where the controller reads custom configuration + // - Services: referenced from Ingress rules and required to obtain + // information about ports and annotations + // - Endpoints: referenced from Services and what the backend uses + // to route traffic + // Any update to services, endpoints, secrets (only those referenced from Ingress) + // and ingress trigger the execution. + // Notifications of type Add, Update and Delete: + // https://github.com/kubernetes/kubernetes/blob/master/pkg/client/cache/controller.go#L164 + // + // ConfigMap content of --configmap + // Configuration returns the translation from Ingress rules containing + // information about all the upstreams (service endpoints ) "virtual" + // servers (FQDN) and all the locations inside each server. Each + // location contains information about all the annotations were configured + // https://k8s.io/ingress/core/blob/master/pkg/ingress/types.go#L83 + // The backend returns the contents of the configuration file or an error + // with the reason why was not possible to generate the file. + // + // The returned configuration is then passed to test, and then to reload + // if there is no errors. + OnUpdate(*api.ConfigMap, Configuration) ([]byte, error) + // BackendDefaults returns the minimum settings required to configure the + // communication to endpoints + BackendDefaults() defaults.Backend + // Info returns information about the ingress controller + Info() *BackendInfo +} + +// 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 +type BackendInfo struct { + // Name returns the name of the backend implementation + Name string `json:"name"` + // Release returns the running version (semver) + Release string `json:"release"` + // Build returns information about the git commit + Build string `json:"build"` + // Repository return information about the git repository + Repository string `json:"repository"` +} + +// Configuration holds the definition of all the parts required to describe all +// ingresses reachable by the ingress controller (using a filter by namespace) +type Configuration struct { + // Backends are a list of backends used by all the Ingress rules in the + // ingress controller. This list includes the default backend + Backends []*Backend `json:"namespace"` + // Servers + Servers []*Server `json:"servers"` + // TCPEndpoints contain endpoints for tcp streams handled by this backend + // +optional + TCPEndpoints []*Location `json:"tcpEndpoints,omitempty"` + // UPDEndpoints contain endpoints for udp streams handled by this backend + // +optional + UPDEndpoints []*Location `json:"udpEndpoints,omitempty"` + // PassthroughBackend contains the backends used for SSL passthrough. + // It contains information about the associated Server Name Indication (SNI). + // +optional + PassthroughBackends []*SSLPassthroughBackend `json:"passthroughBackends,omitempty"` +} + +// Backend describes one or more remote server/s (endpoints) associated with a service +type Backend struct { + // Name represents an unique api.Service name formatted as -- + Name string `json:"name"` + // This indicates if the communication protocol between the backend and the endpoint is HTTP or HTTPS + // Allowing the use of HTTPS + // The endpoint/s must provide a TLS connection. + // The certificate used in the endpoint cannot be a self signed certificate + // TODO: add annotation to allow the load of ca certificate + Secure bool `json:"secure"` + // Endpoints contains the list of endpoints currently running + Endpoints []Endpoint `json:"endpoints"` +} + +// Endpoint describes a kubernetes endpoint in an backend +type Endpoint struct { + // Address IP address of the endpoint + Address string `json:"address"` + // Port number of the TCP port + Port string `json:"port"` + // MaxFails returns the number of unsuccessful attempts to communicate + // allowed before this should be considered dow. + // Setting 0 indicates that the check is performed by a Kubernetes probe + MaxFails int `json:"maxFails"` + // FailTimeout returns the time in seconds during which the specified number + // of unsuccessful attempts to communicate with the server should happen + // to consider the endpoint unavailable + FailTimeout int `json:"failTimeout"` +} + +// Server describes a website +type Server struct { + // Hostname returns the FQDN of the server + Hostname string `json:"hostname"` + // SSLPassthrough indicates if the TLS termination is realized in + // the server or in the remote endpoint + SSLPassthrough bool `json:"sslPassthrough"` + // SSLCertificate path to the SSL certificate on disk + SSLCertificate string `json:"sslCertificate"` + // SSLPemChecksum returns the checksum of the certificate file on disk. + // There is no restriction in the hash generator. This checksim can be + // used to determine if the secret changed without the use of file + // system notifications + SSLPemChecksum string `json:"sslPemChecksum"` + // Locations list of URIs configured in the server. + Locations []*Location `json:"locations,omitempty"` +} + +// Location describes an URI inside a server. +// Also contains additional information about annotations in the Ingress. +// +// Important: +// The implementation of annotations is optional +// +// In some cases when more than one annotations is defined a particular order in the execution +// is required. +// The chain in the execution order of annotations should be: +// - CertificateAuth +// - Whitelist +// - RateLimit +// - BasicDigestAuth +// - ExternalAuth +// - Redirect +type Location struct { + // Path is an extended POSIX regex as defined by IEEE Std 1003.1, + // (i.e this follows the egrep/unix syntax, not the perl syntax) + // matched against the path of an incoming request. Currently it can + // contain characters disallowed from the conventional "path" + // part of a URL as defined by RFC 3986. Paths must begin with + // a '/'. If unspecified, the path defaults to a catch all sending + // traffic to the backend. + Path string `json:"path"` + // IsDefBackend indicates if service specified in the Ingress + // contains active endpoints or not. Returning true means the location + // uses the default backend. + IsDefBackend bool `json:"isDefBackend"` + // Backend describes the name of the backend to use. + Backend string `json:"backend"` + // BasicDigestAuth returns authentication configuration for + // an Ingress rule. + // +optional + BasicDigestAuth auth.BasicDigest `json:"basicDigestAuth,omitempty"` + // EnableCORS indicates if path must support CORS + // +optional + EnableCORS bool `json:"enableCors,omitempty"` + // ExternalAuth indicates the access to this location requires + // authentication using an external provider + // +optional + ExternalAuth authreq.External `json:"externalAuth,omitempty"` + // RateLimit describes a limit in the number of connections per IP + // address or connections per second. + // The Redirect annotation precedes RateLimit + // +optional + RateLimit ratelimit.RateLimit `json:"rateLimit,omitempty"` + // Redirect describes the redirection this location. + // +optional + Redirect rewrite.Redirect `json:"redirect,omitempty"` + // Whitelist indicates only connections from certain client + // addresses or networks are allowed. + // +optional + Whitelist ipwhitelist.SourceRange `json:"whitelist,omitempty"` + // Proxy contains information about timeouts and buffer sizes + // to be used in connections against endpoints + // +optional + Proxy proxy.Configuration `json:"proxy,omitempty"` + // CertificateAuth indicates the access to this location requires + // external authentication + // +optional + CertificateAuth authtls.SSLCert `json:"certificateAuth,omitempty"` +} + +// SSLPassthroughBackend describes a SSL upstream server configured +// as passthrough (no TLS termination in the ingress controller) +// The endpoints must provide the TLS termination exposing the required SSL certificate. +// The ingress controller only pipes the underlying TCP connection +type SSLPassthroughBackend struct { + // Backend describes the endpoints to use. + Backend string `json:"namespace,omitempty"` + // Hostname returns the FQDN of the server + Hostname string `json:"hostname"` +} diff --git a/core/pkg/net/ssl/ssl.go b/core/pkg/net/ssl/ssl.go index a9722fc76f..14a6fbef3d 100644 --- a/core/pkg/net/ssl/ssl.go +++ b/core/pkg/net/ssl/ssl.go @@ -21,6 +21,7 @@ import ( "crypto/x509" "encoding/hex" "encoding/pem" + "errors" "fmt" "io/ioutil" "os" @@ -92,7 +93,8 @@ func AddOrUpdateCertAndKey(name string, cert, key, ca []byte) (*ingress.SSLCert, _, err := pemCert.Verify(opts) if err != nil { - return nil, fmt.Errorf("failed to verify certificate chain: \n\t%s\n", err) + oe := fmt.Sprintf("failed to verify certificate chain: \n\t%s\n", err) + return nil, errors.New(oe) } caName := fmt.Sprintf("ca-%v.pem", name) diff --git a/hack/e2e-internal/e2e-down.sh b/hack/e2e-internal/e2e-down.sh deleted file mode 100755 index 62ee7aec29..0000000000 --- a/hack/e2e-internal/e2e-down.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash - -[[ $DEBUG ]] && set -x - -set -eof pipefail - -# include env -. hack/e2e-internal/e2e-env.sh - -echo "Destroying running docker containers..." -# do not failt if the container is not running -docker rm -f kubelet || true -docker rm -f apiserver || true -docker rm -f etcd || true diff --git a/hack/e2e-internal/e2e-env.sh b/hack/e2e-internal/e2e-env.sh deleted file mode 100755 index d0747bb6e0..0000000000 --- a/hack/e2e-internal/e2e-env.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env bash - -[[ $DEBUG ]] && set -x - -export ETCD_VERSION=3.0.14 -export K8S_VERSION=1.4.5 - -export PWD=`pwd` -export BASEDIR="$(dirname ${BASH_SOURCE})" -export KUBECTL="${BASEDIR}/kubectl" -export GOOS="${GOOS:-linux}" - -if [ ! -e ${KUBECTL} ]; then - echo "kubectl binary is missing. downloading..." - curl -sSL http://storage.googleapis.com/kubernetes-release/release/v${K8S_VERSION}/bin/${GOOS}/amd64/kubectl -o ${KUBECTL} - chmod u+x ${KUBECTL} -fi - -${KUBECTL} config set-cluster travis --server=http://0.0.0.0:8080 -${KUBECTL} config set-context travis --cluster=travis -${KUBECTL} config use-context travis diff --git a/hack/e2e-internal/e2e-status.sh b/hack/e2e-internal/e2e-status.sh deleted file mode 100755 index 21a4e9b291..0000000000 --- a/hack/e2e-internal/e2e-status.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash - -[[ $DEBUG ]] && set -x - -set -eof pipefail - -# include env -. hack/e2e-internal/e2e-env.sh - -echo "Kubernetes information:" -${KUBECTL} version diff --git a/hack/e2e-internal/e2e-up.sh b/hack/e2e-internal/e2e-up.sh deleted file mode 100755 index 15b2d46312..0000000000 --- a/hack/e2e-internal/e2e-up.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env bash - -[[ $DEBUG ]] && set -x - -set -eof pipefail - -# include env -. hack/e2e-internal/e2e-env.sh - -echo "Starting etcd..." -docker run -d \ - --net=host \ - --name=etcd \ - quay.io/coreos/etcd:v$ETCD_VERSION - -echo "Starting kubernetes..." - -docker run -d --name=apiserver \ - --net=host \ - --pid=host \ - --privileged=true \ - gcr.io/google_containers/hyperkube:v${K8S_VERSION} \ - /hyperkube apiserver \ - --insecure-bind-address=0.0.0.0 \ - --service-cluster-ip-range=10.0.0.1/24 \ - --etcd_servers=http://127.0.0.1:4001 \ - --v=2 - -docker run -d --name=kubelet \ - --volume=/:/rootfs:ro \ - --volume=/sys:/sys:ro \ - --volume=/dev:/dev \ - --volume=/var/lib/docker/:/var/lib/docker:rw \ - --volume=/var/lib/kubelet/:/var/lib/kubelet:rw \ - --volume=/var/run:/var/run:rw \ - --net=host \ - --pid=host \ - --privileged=true \ - gcr.io/google_containers/hyperkube:v${K8S_VERSION} \ - /hyperkube kubelet \ - --containerized \ - --hostname-override="0.0.0.0" \ - --address="0.0.0.0" \ - --cluster_dns=10.0.0.10 --cluster_domain=cluster.local \ - --api-servers=http://localhost:8080 \ - --config=/etc/kubernetes/manifests-multi - -echo "waiting until api server is available..." -until curl -o /dev/null -sIf http://0.0.0.0:8080; do \ - sleep 10; -done; - -echo "Kubernetes started" -echo "Kubernetes information:" -${KUBECTL} version diff --git a/hack/e2e-internal/ginkgo-e2e.sh b/hack/e2e-internal/ginkgo-e2e.sh deleted file mode 100755 index aa3c61ce6e..0000000000 --- a/hack/e2e-internal/ginkgo-e2e.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash - -echo "running ginkgo" \ No newline at end of file diff --git a/hack/e2e.go b/hack/e2e.go deleted file mode 100644 index d6ef3fa060..0000000000 --- a/hack/e2e.go +++ /dev/null @@ -1,285 +0,0 @@ -/* -Copyright 2014 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. -*/ - -// e2e.go runs the e2e test suite. No non-standard package dependencies; call with "go run". -package main - -import ( - "encoding/xml" - "flag" - "fmt" - "io/ioutil" - "log" - "os" - "os/exec" - "path/filepath" - "strings" - "time" -) - -var ( - build = flag.Bool("build", true, "Build the backends images indicated by the env var BACKENDS required to run e2e tests.") - up = flag.Bool("up", true, "Creates a kubernetes cluster using hyperkube (containerized kubelet).") - down = flag.Bool("down", true, "destroys the created cluster.") - test = flag.Bool("test", true, "Run Ginkgo tests.") - dump = flag.String("dump", "", "If set, dump cluster logs to this location on test or cluster-up failure") - testArgs = flag.String("test-args", "", "Space-separated list of arguments to pass to Ginkgo test runner.") - deployment = flag.String("deployment", "bash", "up/down mechanism") - verbose = flag.Bool("v", false, "If true, print all command output.") -) - -func appendError(errs []error, err error) []error { - if err != nil { - return append(errs, err) - } - return errs -} - -func validWorkingDirectory() error { - cwd, err := os.Getwd() - if err != nil { - return fmt.Errorf("could not get pwd: %v", err) - } - acwd, err := filepath.Abs(cwd) - if err != nil { - return fmt.Errorf("failed to convert %s to an absolute path: %v", cwd, err) - } - if !strings.Contains(filepath.Base(acwd), "ingress-controller") { - return fmt.Errorf("must run from git root directory: %v", acwd) - } - return nil -} - -type TestCase struct { - XMLName xml.Name `xml:"testcase"` - ClassName string `xml:"classname,attr"` - Name string `xml:"name,attr"` - Time float64 `xml:"time,attr"` - Failure string `xml:"failure,omitempty"` -} - -type TestSuite struct { - XMLName xml.Name `xml:"testsuite"` - Failures int `xml:"failures,attr"` - Tests int `xml:"tests,attr"` - Time float64 `xml:"time,attr"` - Cases []TestCase -} - -var suite TestSuite - -func xmlWrap(name string, f func() error) error { - start := time.Now() - err := f() - duration := time.Since(start) - c := TestCase{ - Name: name, - ClassName: "e2e.go", - Time: duration.Seconds(), - } - if err != nil { - c.Failure = err.Error() - suite.Failures++ - } - suite.Cases = append(suite.Cases, c) - suite.Tests++ - return err -} - -func writeXML(start time.Time) { - suite.Time = time.Since(start).Seconds() - out, err := xml.MarshalIndent(&suite, "", " ") - if err != nil { - log.Fatalf("Could not marshal XML: %s", err) - } - path := filepath.Join(*dump, "junit_runner.xml") - f, err := os.Create(path) - if err != nil { - log.Fatalf("Could not create file: %s", err) - } - defer f.Close() - if _, err := f.WriteString(xml.Header); err != nil { - log.Fatalf("Error writing XML header: %s", err) - } - if _, err := f.Write(out); err != nil { - log.Fatalf("Error writing XML data: %s", err) - } - log.Printf("Saved XML output to %s.", path) -} - -func main() { - log.SetFlags(log.LstdFlags | log.Lshortfile) - flag.Parse() - - if err := validWorkingDirectory(); err != nil { - log.Fatalf("Called from invalid working directory: %v", err) - } - - deploy, err := getDeployer() - if err != nil { - log.Fatalf("Error creating deployer: %v", err) - } - - if err := run(deploy); err != nil { - log.Fatalf("Something went wrong: %s", err) - } -} - -func run(deploy deployer) error { - if *dump != "" { - defer writeXML(time.Now()) - } - - if *build { - if err := xmlWrap("Build", Build); err != nil { - return fmt.Errorf("error building: %s", err) - } - } - - if *up { - if err := xmlWrap("TearDown", deploy.Down); err != nil { - return fmt.Errorf("error tearing down previous cluster: %s", err) - } - } - - var errs []error - - if *up { - // If we tried to bring the cluster up, make a courtesy - // attempt to bring it down so we're not leaving resources around. - // - // TODO: We should try calling deploy.Down exactly once. Though to - // stop the leaking resources for now, we want to be on the safe side - // and call it explictly in defer if the other one is not called. - if *down { - defer xmlWrap("Deferred TearDown", deploy.Down) - } - // Start the cluster using this version. - if err := xmlWrap("Up", deploy.Up); err != nil { - return fmt.Errorf("starting e2e cluster: %s", err) - } - if *dump != "" { - cmd := exec.Command("./cluster/kubectl.sh", "--match-server-version=false", "get", "nodes", "-oyaml") - b, err := cmd.CombinedOutput() - if *verbose { - log.Printf("kubectl get nodes:\n%s", string(b)) - } - if err == nil { - if err := ioutil.WriteFile(filepath.Join(*dump, "nodes.yaml"), b, 0644); err != nil { - errs = appendError(errs, fmt.Errorf("error writing nodes.yaml: %v", err)) - } - } else { - errs = appendError(errs, fmt.Errorf("error running get nodes: %v", err)) - } - } - } - - if *test { - if err := xmlWrap("IsUp", deploy.IsUp); err != nil { - errs = appendError(errs, err) - } else { - errs = appendError(errs, Test()) - } - } - - if len(errs) > 0 && *dump != "" { - errs = appendError(errs, xmlWrap("DumpClusterLogs", func() error { - return DumpClusterLogs(*dump) - })) - } - - if *down { - errs = appendError(errs, xmlWrap("TearDown", deploy.Down)) - } - - if len(errs) != 0 { - return fmt.Errorf("encountered %d errors: %v", len(errs), errs) - } - return nil -} - -func Build() error { - // The build-release script needs stdin to ask the user whether - // it's OK to download the docker image. - cmd := exec.Command("make", "backends", "backends-images", "backends-push") - cmd.Stdin = os.Stdin - if err := finishRunning("build-release", cmd); err != nil { - return fmt.Errorf("error building: %v", err) - } - return nil -} - -type deployer interface { - Up() error - IsUp() error - SetupKubecfg() error - Down() error -} - -func getDeployer() (deployer, error) { - switch *deployment { - case "bash": - return bash{}, nil - default: - return nil, fmt.Errorf("Unknown deployment strategy %q", *deployment) - } -} - -type bash struct{} - -func (b bash) Up() error { - return finishRunning("up", exec.Command("./hack/e2e-internal/e2e-up.sh")) -} - -func (b bash) IsUp() error { - return finishRunning("get status", exec.Command("./hack/e2e-internal/e2e-status.sh")) -} - -func (b bash) SetupKubecfg() error { - return nil -} - -func (b bash) Down() error { - return finishRunning("teardown", exec.Command("./hack/e2e-internal/e2e-down.sh")) -} - -func DumpClusterLogs(location string) error { - log.Printf("Dumping cluster logs to: %v", location) - return finishRunning("dump cluster logs", exec.Command("./hack/e2e-internal/log-dump.sh", location)) -} - -func Test() error { - if *testArgs == "" { - *testArgs = "--ginkgo.focus=\\[Feature:Ingress\\]" - } - return finishRunning("Ginkgo tests", exec.Command("./hack/e2e-internal/ginkgo-e2e.sh", strings.Fields(*testArgs)...)) -} - -func finishRunning(stepName string, cmd *exec.Cmd) error { - if *verbose { - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - } - log.Printf("Running: %v", stepName) - defer func(start time.Time) { - log.Printf("Step '%s' finished in %s", stepName, time.Since(start)) - }(time.Now()) - - if err := cmd.Run(); err != nil { - return fmt.Errorf("error running %v: %v", stepName, err) - } - return nil -} From 42b58e957c1704b4c228ffe1f14e502f4d445b70 Mon Sep 17 00:00:00 2001 From: Manuel de Brito Fontes Date: Wed, 23 Nov 2016 21:14:14 -0300 Subject: [PATCH 4/5] Avoid nginx reloads --- controllers/nginx/pkg/cmd/controller/nginx.go | 16 ++++++---------- core/pkg/ingress/controller/backend_ssl.go | 4 +++- core/pkg/ingress/controller/controller.go | 16 ++++++++-------- core/pkg/ingress/types.go | 10 +++------- 4 files changed, 20 insertions(+), 26 deletions(-) diff --git a/controllers/nginx/pkg/cmd/controller/nginx.go b/controllers/nginx/pkg/cmd/controller/nginx.go index 757e6aaaff..92ff980c9f 100644 --- a/controllers/nginx/pkg/cmd/controller/nginx.go +++ b/controllers/nginx/pkg/cmd/controller/nginx.go @@ -105,22 +105,18 @@ func (n NGINXController) Start() { // Reload checks if the running configuration file is different // to the specified and reload nginx if required -func (n NGINXController) Reload(data []byte) ([]byte, error) { +func (n NGINXController) Reload(data []byte) ([]byte, bool, error) { if !n.isReloadRequired(data) { - return nil, fmt.Errorf("Reload not required") + return []byte("Reload not required"), false, nil } err := ioutil.WriteFile(cfgPath, data, 0644) if err != nil { - return nil, err + return nil, false, err } - return exec.Command(n.binary, "-s", "reload").CombinedOutput() -} - -// Test checks is a file contains a valid NGINX configuration -func (n NGINXController) Test(file string) *exec.Cmd { - return exec.Command(n.binary, "-t", "-c", file) + o, e := exec.Command(n.binary, "-s", "reload").CombinedOutput() + return o, true, e } // BackendDefaults returns the nginx defaults @@ -188,7 +184,7 @@ func (n NGINXController) testTemplate(cfg []byte) error { } defer tmpfile.Close() ioutil.WriteFile(tmpfile.Name(), cfg, 0644) - out, err := n.Test(tmpfile.Name()).CombinedOutput() + out, err := exec.Command(n.binary, "-t", "-c", tmpfile.Name()).CombinedOutput() if err != nil { // this error is different from the rest because it must be clear why nginx is not working oe := fmt.Sprintf(` diff --git a/core/pkg/ingress/controller/backend_ssl.go b/core/pkg/ingress/controller/backend_ssl.go index d6f2f0c548..aa17c7807c 100644 --- a/core/pkg/ingress/controller/backend_ssl.go +++ b/core/pkg/ingress/controller/backend_ssl.go @@ -89,9 +89,11 @@ func (ic *GenericController) syncSecret(k interface{}) error { // create certificates and add or update the item in the store _, exists = ic.sslCertTracker.Get(key) if exists { + glog.V(3).Infof("updating secret %v/%v in the store ", sec.Namespace, sec.Name) ic.sslCertTracker.Update(key, cert) return nil } + glog.V(3).Infof("adding secret %v/%v to the store ", sec.Namespace, sec.Name) ic.sslCertTracker.Add(key, cert) return nil } @@ -99,7 +101,7 @@ func (ic *GenericController) syncSecret(k interface{}) error { func (ic *GenericController) getPemCertificate(secretName string) (*ingress.SSLCert, error) { secretInterface, exists, err := ic.secrLister.Store.GetByKey(secretName) if err != nil { - return nil, fmt.Errorf("Error retriveing secret %v: %v", secretName, err) + return nil, fmt.Errorf("error retriveing secret %v: %v", secretName, err) } if !exists { return nil, fmt.Errorf("secret named %v does not exists", secretName) diff --git a/core/pkg/ingress/controller/controller.go b/core/pkg/ingress/controller/controller.go index 0d349a3d9a..655d7ea8ab 100644 --- a/core/pkg/ingress/controller/controller.go +++ b/core/pkg/ingress/controller/controller.go @@ -386,14 +386,16 @@ func (ic *GenericController) sync(key interface{}) error { return err } - out, err := ic.cfg.Backend.Reload(data) + out, reloaded, err := ic.cfg.Backend.Reload(data) if err != nil { incReloadErrorCount() glog.Errorf("unexpected failure restarting the backend: \n%v", string(out)) return err } - glog.Infof("ingress backend successfully reloaded...") - incReloadCount() + if reloaded { + glog.Infof("ingress backend successfully reloaded...") + incReloadCount() + } return nil } @@ -686,7 +688,6 @@ func (ic *GenericController) getBackendServers() ([]*ingress.Backend, []*ingress loc.BasicDigestAuth = *nginxAuth loc.RateLimit = *rl loc.Redirect = *locRew - //loc.SecureUpstream = secUpstream loc.Whitelist = *wl loc.Backend = ups.Name loc.EnableCORS = eCORS @@ -706,7 +707,6 @@ func (ic *GenericController) getBackendServers() ([]*ingress.Backend, []*ingress BasicDigestAuth: *nginxAuth, RateLimit: *rl, Redirect: *locRew, - //SecureUpstream: secUpstream, Whitelist: *wl, EnableCORS: eCORS, ExternalAuth: ra, @@ -921,7 +921,7 @@ func (ic *GenericController) createServers(data []interface{}, upstreams map[str host = defServerName } - // only add certificate if the server does not have one previously configured + // only add a certificate if the server does not have one previously configured if len(ing.Spec.TLS) > 0 && servers[host].SSLCertificate != "" { key := fmt.Sprintf("%v/%v", ing.Namespace, ing.Spec.TLS[0].SecretName) bc, exists := ic.sslCertTracker.Get(key) @@ -1048,8 +1048,8 @@ func (ic GenericController) Start() { go ic.secrController.Run(ic.stopCh) go ic.mapController.Run(ic.stopCh) - go ic.secretQueue.Run(time.Second, ic.stopCh) - go ic.syncQueue.Run(time.Second, ic.stopCh) + go ic.secretQueue.Run(5*time.Second, ic.stopCh) + go ic.syncQueue.Run(5*time.Second, ic.stopCh) go ic.syncStatus.Run(ic.stopCh) diff --git a/core/pkg/ingress/types.go b/core/pkg/ingress/types.go index dd490ad701..c1dfc0fa20 100644 --- a/core/pkg/ingress/types.go +++ b/core/pkg/ingress/types.go @@ -17,8 +17,6 @@ limitations under the License. package ingress import ( - "os/exec" - "k8s.io/kubernetes/pkg/api" "k8s.io/ingress/core/pkg/ingress/annotations/auth" @@ -43,15 +41,13 @@ var ( // TODO (#18): Make sure this is sufficiently supportive of other backends. type Controller interface { // Reload takes a byte array representing the new loadbalancer configuration, - // and returns a byte array containing any output/errors from the backend. + // and returns a byte array containing any output/errors from the backend and + // if a reload was required. // Before returning the backend must load the configuration in the given array // into the loadbalancer and restart it, or fail with an error and message string. // If reloading fails, there should be not change in the running configuration or // the given byte array. - Reload(data []byte) ([]byte, error) - // Tests returns the commands to execute that verifies if the configuration file is valid - // Example: nginx -t -c - Test(file string) *exec.Cmd + Reload(data []byte) ([]byte, bool, error) // OnUpdate callback invoked from the sync queue https://k8s.io/ingress/core/blob/master/pkg/ingress/controller/controller.go#L387 // when an update occurs. This is executed frequently because Ingress // controllers watches changes in: From 16c580054509b4b3451ae7636d17949678ebc2ae Mon Sep 17 00:00:00 2001 From: Manuel de Brito Fontes Date: Wed, 23 Nov 2016 20:22:29 -0300 Subject: [PATCH 5/5] Add e2e boilerplate --- .../rootfs/etc/nginx/template/nginx.tmpl | 2 +- core/pkg/ingress/controller/backend_ssl.go | 2 +- core/pkg/ingress/controller/controller.go | 8 +- hack/e2e-internal/e2e-down.sh | 14 + hack/e2e-internal/e2e-env.sh | 21 ++ hack/e2e-internal/e2e-status.sh | 11 + hack/e2e-internal/e2e-up.sh | 55 ++++ hack/e2e-internal/ginkgo-e2e.sh | 3 + hack/e2e.go | 285 ++++++++++++++++++ 9 files changed, 397 insertions(+), 4 deletions(-) create mode 100755 hack/e2e-internal/e2e-down.sh create mode 100755 hack/e2e-internal/e2e-env.sh create mode 100755 hack/e2e-internal/e2e-status.sh create mode 100755 hack/e2e-internal/e2e-up.sh create mode 100755 hack/e2e-internal/ginkgo-e2e.sh create mode 100644 hack/e2e.go diff --git a/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl b/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl index 30774f6f6a..906afd370c 100644 --- a/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl +++ b/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl @@ -188,7 +188,7 @@ http { server { server_name {{ $server.Hostname }}; listen 80{{ if $cfg.UseProxyProtocol }} proxy_protocol{{ end }}; - {{ if not (empty $server.SSLCertificate) }}listen 442 {{ if $cfg.UseProxyProtocol }}proxy_protocol{{ end }} ssl {{ if $cfg.UseHttp2 }}http2{{ end }}; + {{ if not (empty $server.SSLCertificate) }}listen 442 {{ if $cfg.UseProxyProtocol }}proxy_protocol{{ end }} ssl {{ if $cfg.UseHTTP2 }}http2{{ end }}; {{/* comment PEM sha is required to detect changes in the generated configuration and force a reload */}} # PEM sha: {{ $server.SSLPemChecksum }} ssl_certificate {{ $server.SSLCertificate }}; diff --git a/core/pkg/ingress/controller/backend_ssl.go b/core/pkg/ingress/controller/backend_ssl.go index aa17c7807c..92c32fc8c8 100644 --- a/core/pkg/ingress/controller/backend_ssl.go +++ b/core/pkg/ingress/controller/backend_ssl.go @@ -77,7 +77,7 @@ func (ic *GenericController) syncSecret(k interface{}) error { } sec := secObj.(*api.Secret) if !ic.secrReferenced(sec.Name, sec.Namespace) { - glog.V(2).Infof("secret %v/%v is not used in Ingress rules. skipping ", sec.Namespace, sec.Name) + glog.V(3).Infof("secret %v/%v is not used in Ingress rules. skipping ", sec.Namespace, sec.Name) return nil } diff --git a/core/pkg/ingress/controller/controller.go b/core/pkg/ingress/controller/controller.go index 655d7ea8ab..1306e4e014 100644 --- a/core/pkg/ingress/controller/controller.go +++ b/core/pkg/ingress/controller/controller.go @@ -100,7 +100,8 @@ type GenericController struct { syncStatus status.Sync - // controller for SSL certificates + // local store of SSL certificates + // (only certificates used in ingress) sslCertTracker *sslCertTracker // TaskQueue in charge of keep the secrets referenced from Ingress // in sync with the files on disk @@ -922,7 +923,8 @@ func (ic *GenericController) createServers(data []interface{}, upstreams map[str } // only add a certificate if the server does not have one previously configured - if len(ing.Spec.TLS) > 0 && servers[host].SSLCertificate != "" { + // TODO: TLS without secret? + if len(ing.Spec.TLS) > 0 && servers[host].SSLCertificate == "" && ing.Spec.TLS[0].SecretName != "" { key := fmt.Sprintf("%v/%v", ing.Namespace, ing.Spec.TLS[0].SecretName) bc, exists := ic.sslCertTracker.Get(key) if exists { @@ -931,6 +933,8 @@ func (ic *GenericController) createServers(data []interface{}, upstreams map[str servers[host].SSLCertificate = cert.PemFileName servers[host].SSLPemChecksum = cert.PemSHA } + } else { + glog.Warningf("secret %v does not exists", key) } } diff --git a/hack/e2e-internal/e2e-down.sh b/hack/e2e-internal/e2e-down.sh new file mode 100755 index 0000000000..62ee7aec29 --- /dev/null +++ b/hack/e2e-internal/e2e-down.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +[[ $DEBUG ]] && set -x + +set -eof pipefail + +# include env +. hack/e2e-internal/e2e-env.sh + +echo "Destroying running docker containers..." +# do not failt if the container is not running +docker rm -f kubelet || true +docker rm -f apiserver || true +docker rm -f etcd || true diff --git a/hack/e2e-internal/e2e-env.sh b/hack/e2e-internal/e2e-env.sh new file mode 100755 index 0000000000..d0747bb6e0 --- /dev/null +++ b/hack/e2e-internal/e2e-env.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +[[ $DEBUG ]] && set -x + +export ETCD_VERSION=3.0.14 +export K8S_VERSION=1.4.5 + +export PWD=`pwd` +export BASEDIR="$(dirname ${BASH_SOURCE})" +export KUBECTL="${BASEDIR}/kubectl" +export GOOS="${GOOS:-linux}" + +if [ ! -e ${KUBECTL} ]; then + echo "kubectl binary is missing. downloading..." + curl -sSL http://storage.googleapis.com/kubernetes-release/release/v${K8S_VERSION}/bin/${GOOS}/amd64/kubectl -o ${KUBECTL} + chmod u+x ${KUBECTL} +fi + +${KUBECTL} config set-cluster travis --server=http://0.0.0.0:8080 +${KUBECTL} config set-context travis --cluster=travis +${KUBECTL} config use-context travis diff --git a/hack/e2e-internal/e2e-status.sh b/hack/e2e-internal/e2e-status.sh new file mode 100755 index 0000000000..21a4e9b291 --- /dev/null +++ b/hack/e2e-internal/e2e-status.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +[[ $DEBUG ]] && set -x + +set -eof pipefail + +# include env +. hack/e2e-internal/e2e-env.sh + +echo "Kubernetes information:" +${KUBECTL} version diff --git a/hack/e2e-internal/e2e-up.sh b/hack/e2e-internal/e2e-up.sh new file mode 100755 index 0000000000..15b2d46312 --- /dev/null +++ b/hack/e2e-internal/e2e-up.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash + +[[ $DEBUG ]] && set -x + +set -eof pipefail + +# include env +. hack/e2e-internal/e2e-env.sh + +echo "Starting etcd..." +docker run -d \ + --net=host \ + --name=etcd \ + quay.io/coreos/etcd:v$ETCD_VERSION + +echo "Starting kubernetes..." + +docker run -d --name=apiserver \ + --net=host \ + --pid=host \ + --privileged=true \ + gcr.io/google_containers/hyperkube:v${K8S_VERSION} \ + /hyperkube apiserver \ + --insecure-bind-address=0.0.0.0 \ + --service-cluster-ip-range=10.0.0.1/24 \ + --etcd_servers=http://127.0.0.1:4001 \ + --v=2 + +docker run -d --name=kubelet \ + --volume=/:/rootfs:ro \ + --volume=/sys:/sys:ro \ + --volume=/dev:/dev \ + --volume=/var/lib/docker/:/var/lib/docker:rw \ + --volume=/var/lib/kubelet/:/var/lib/kubelet:rw \ + --volume=/var/run:/var/run:rw \ + --net=host \ + --pid=host \ + --privileged=true \ + gcr.io/google_containers/hyperkube:v${K8S_VERSION} \ + /hyperkube kubelet \ + --containerized \ + --hostname-override="0.0.0.0" \ + --address="0.0.0.0" \ + --cluster_dns=10.0.0.10 --cluster_domain=cluster.local \ + --api-servers=http://localhost:8080 \ + --config=/etc/kubernetes/manifests-multi + +echo "waiting until api server is available..." +until curl -o /dev/null -sIf http://0.0.0.0:8080; do \ + sleep 10; +done; + +echo "Kubernetes started" +echo "Kubernetes information:" +${KUBECTL} version diff --git a/hack/e2e-internal/ginkgo-e2e.sh b/hack/e2e-internal/ginkgo-e2e.sh new file mode 100755 index 0000000000..aa3c61ce6e --- /dev/null +++ b/hack/e2e-internal/ginkgo-e2e.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +echo "running ginkgo" \ No newline at end of file diff --git a/hack/e2e.go b/hack/e2e.go new file mode 100644 index 0000000000..d6ef3fa060 --- /dev/null +++ b/hack/e2e.go @@ -0,0 +1,285 @@ +/* +Copyright 2014 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. +*/ + +// e2e.go runs the e2e test suite. No non-standard package dependencies; call with "go run". +package main + +import ( + "encoding/xml" + "flag" + "fmt" + "io/ioutil" + "log" + "os" + "os/exec" + "path/filepath" + "strings" + "time" +) + +var ( + build = flag.Bool("build", true, "Build the backends images indicated by the env var BACKENDS required to run e2e tests.") + up = flag.Bool("up", true, "Creates a kubernetes cluster using hyperkube (containerized kubelet).") + down = flag.Bool("down", true, "destroys the created cluster.") + test = flag.Bool("test", true, "Run Ginkgo tests.") + dump = flag.String("dump", "", "If set, dump cluster logs to this location on test or cluster-up failure") + testArgs = flag.String("test-args", "", "Space-separated list of arguments to pass to Ginkgo test runner.") + deployment = flag.String("deployment", "bash", "up/down mechanism") + verbose = flag.Bool("v", false, "If true, print all command output.") +) + +func appendError(errs []error, err error) []error { + if err != nil { + return append(errs, err) + } + return errs +} + +func validWorkingDirectory() error { + cwd, err := os.Getwd() + if err != nil { + return fmt.Errorf("could not get pwd: %v", err) + } + acwd, err := filepath.Abs(cwd) + if err != nil { + return fmt.Errorf("failed to convert %s to an absolute path: %v", cwd, err) + } + if !strings.Contains(filepath.Base(acwd), "ingress-controller") { + return fmt.Errorf("must run from git root directory: %v", acwd) + } + return nil +} + +type TestCase struct { + XMLName xml.Name `xml:"testcase"` + ClassName string `xml:"classname,attr"` + Name string `xml:"name,attr"` + Time float64 `xml:"time,attr"` + Failure string `xml:"failure,omitempty"` +} + +type TestSuite struct { + XMLName xml.Name `xml:"testsuite"` + Failures int `xml:"failures,attr"` + Tests int `xml:"tests,attr"` + Time float64 `xml:"time,attr"` + Cases []TestCase +} + +var suite TestSuite + +func xmlWrap(name string, f func() error) error { + start := time.Now() + err := f() + duration := time.Since(start) + c := TestCase{ + Name: name, + ClassName: "e2e.go", + Time: duration.Seconds(), + } + if err != nil { + c.Failure = err.Error() + suite.Failures++ + } + suite.Cases = append(suite.Cases, c) + suite.Tests++ + return err +} + +func writeXML(start time.Time) { + suite.Time = time.Since(start).Seconds() + out, err := xml.MarshalIndent(&suite, "", " ") + if err != nil { + log.Fatalf("Could not marshal XML: %s", err) + } + path := filepath.Join(*dump, "junit_runner.xml") + f, err := os.Create(path) + if err != nil { + log.Fatalf("Could not create file: %s", err) + } + defer f.Close() + if _, err := f.WriteString(xml.Header); err != nil { + log.Fatalf("Error writing XML header: %s", err) + } + if _, err := f.Write(out); err != nil { + log.Fatalf("Error writing XML data: %s", err) + } + log.Printf("Saved XML output to %s.", path) +} + +func main() { + log.SetFlags(log.LstdFlags | log.Lshortfile) + flag.Parse() + + if err := validWorkingDirectory(); err != nil { + log.Fatalf("Called from invalid working directory: %v", err) + } + + deploy, err := getDeployer() + if err != nil { + log.Fatalf("Error creating deployer: %v", err) + } + + if err := run(deploy); err != nil { + log.Fatalf("Something went wrong: %s", err) + } +} + +func run(deploy deployer) error { + if *dump != "" { + defer writeXML(time.Now()) + } + + if *build { + if err := xmlWrap("Build", Build); err != nil { + return fmt.Errorf("error building: %s", err) + } + } + + if *up { + if err := xmlWrap("TearDown", deploy.Down); err != nil { + return fmt.Errorf("error tearing down previous cluster: %s", err) + } + } + + var errs []error + + if *up { + // If we tried to bring the cluster up, make a courtesy + // attempt to bring it down so we're not leaving resources around. + // + // TODO: We should try calling deploy.Down exactly once. Though to + // stop the leaking resources for now, we want to be on the safe side + // and call it explictly in defer if the other one is not called. + if *down { + defer xmlWrap("Deferred TearDown", deploy.Down) + } + // Start the cluster using this version. + if err := xmlWrap("Up", deploy.Up); err != nil { + return fmt.Errorf("starting e2e cluster: %s", err) + } + if *dump != "" { + cmd := exec.Command("./cluster/kubectl.sh", "--match-server-version=false", "get", "nodes", "-oyaml") + b, err := cmd.CombinedOutput() + if *verbose { + log.Printf("kubectl get nodes:\n%s", string(b)) + } + if err == nil { + if err := ioutil.WriteFile(filepath.Join(*dump, "nodes.yaml"), b, 0644); err != nil { + errs = appendError(errs, fmt.Errorf("error writing nodes.yaml: %v", err)) + } + } else { + errs = appendError(errs, fmt.Errorf("error running get nodes: %v", err)) + } + } + } + + if *test { + if err := xmlWrap("IsUp", deploy.IsUp); err != nil { + errs = appendError(errs, err) + } else { + errs = appendError(errs, Test()) + } + } + + if len(errs) > 0 && *dump != "" { + errs = appendError(errs, xmlWrap("DumpClusterLogs", func() error { + return DumpClusterLogs(*dump) + })) + } + + if *down { + errs = appendError(errs, xmlWrap("TearDown", deploy.Down)) + } + + if len(errs) != 0 { + return fmt.Errorf("encountered %d errors: %v", len(errs), errs) + } + return nil +} + +func Build() error { + // The build-release script needs stdin to ask the user whether + // it's OK to download the docker image. + cmd := exec.Command("make", "backends", "backends-images", "backends-push") + cmd.Stdin = os.Stdin + if err := finishRunning("build-release", cmd); err != nil { + return fmt.Errorf("error building: %v", err) + } + return nil +} + +type deployer interface { + Up() error + IsUp() error + SetupKubecfg() error + Down() error +} + +func getDeployer() (deployer, error) { + switch *deployment { + case "bash": + return bash{}, nil + default: + return nil, fmt.Errorf("Unknown deployment strategy %q", *deployment) + } +} + +type bash struct{} + +func (b bash) Up() error { + return finishRunning("up", exec.Command("./hack/e2e-internal/e2e-up.sh")) +} + +func (b bash) IsUp() error { + return finishRunning("get status", exec.Command("./hack/e2e-internal/e2e-status.sh")) +} + +func (b bash) SetupKubecfg() error { + return nil +} + +func (b bash) Down() error { + return finishRunning("teardown", exec.Command("./hack/e2e-internal/e2e-down.sh")) +} + +func DumpClusterLogs(location string) error { + log.Printf("Dumping cluster logs to: %v", location) + return finishRunning("dump cluster logs", exec.Command("./hack/e2e-internal/log-dump.sh", location)) +} + +func Test() error { + if *testArgs == "" { + *testArgs = "--ginkgo.focus=\\[Feature:Ingress\\]" + } + return finishRunning("Ginkgo tests", exec.Command("./hack/e2e-internal/ginkgo-e2e.sh", strings.Fields(*testArgs)...)) +} + +func finishRunning(stepName string, cmd *exec.Cmd) error { + if *verbose { + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + } + log.Printf("Running: %v", stepName) + defer func(start time.Time) { + log.Printf("Step '%s' finished in %s", stepName, time.Since(start)) + }(time.Now()) + + if err := cmd.Run(); err != nil { + return fmt.Errorf("error running %v: %v", stepName, err) + } + return nil +}