diff options
author | Yibo Cai <yibo.cai@linaro.org> | 2017-08-14 12:55:52 +0800 |
---|---|---|
committer | Fathi Boudra <fathi.boudra@linaro.org> | 2017-08-14 17:12:08 +0300 |
commit | 5da9d308e2e5b7a106f40ca57fd5a8c29dc8b605 (patch) | |
tree | a029db449aad382a246eab76b4e240b6f4e78406 /xenial-arm64-leg-nginx-ingress-controller | |
parent | 36b26e9e12c92deba69897d1a5e24dbb02bab0ce (diff) |
xenial-arm64-leg-nginx-ingress-controller: new docker image
Change-Id: I55c97266aa00df202ff0cb8dc599692f8893360a
Diffstat (limited to 'xenial-arm64-leg-nginx-ingress-controller')
5 files changed, 721 insertions, 0 deletions
diff --git a/xenial-arm64-leg-nginx-ingress-controller/Dockerfile b/xenial-arm64-leg-nginx-ingress-controller/Dockerfile new file mode 100644 index 00000000..5d74c9f1 --- /dev/null +++ b/xenial-arm64-leg-nginx-ingress-controller/Dockerfile @@ -0,0 +1,32 @@ +# Copyright 2015 The Kubernetes Authors. All rights reserved. +# +# 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. + +FROM gcr.io/google_containers/nginx-slim-arm64:0.23 + +#CROSS_BUILD_COPY qemu-aarch64-static /usr/bin/ + +RUN DEBIAN_FRONTEND=noninteractive apt-get update \ + && apt-get install -y --no-install-recommends \ + diffutils \ + && rm -rf /var/lib/apt/lists/* + +RUN curl -sSL -o /tmp/dumb-init.deb http://ftp.us.debian.org/debian/pool/main/d/dumb-init/dumb-init_1.2.0-1_arm64.deb \ + && dpkg -i /tmp/dumb-init.deb \ + && rm /tmp/dumb-init.deb + +ENTRYPOINT ["/usr/bin/dumb-init"] + +COPY . / + +CMD ["/nginx-ingress-controller"] diff --git a/xenial-arm64-leg-nginx-ingress-controller/build.sh b/xenial-arm64-leg-nginx-ingress-controller/build.sh new file mode 100755 index 00000000..4c51a816 --- /dev/null +++ b/xenial-arm64-leg-nginx-ingress-controller/build.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +set -e + +image=linaro/ci-arm64-leg-nginx-ingress-controller-ubuntu:xenial +docker build --pull --tag=$image . +echo $image > .docker-tag diff --git a/xenial-arm64-leg-nginx-ingress-controller/etc/nginx/nginx.conf b/xenial-arm64-leg-nginx-ingress-controller/etc/nginx/nginx.conf new file mode 100644 index 00000000..bb36624c --- /dev/null +++ b/xenial-arm64-leg-nginx-ingress-controller/etc/nginx/nginx.conf @@ -0,0 +1,6 @@ +# A very simple nginx configuration file that forces nginx to start. +pid /run/nginx.pid; + +events {} +http {} +daemon off;
\ No newline at end of file diff --git a/xenial-arm64-leg-nginx-ingress-controller/etc/nginx/template/nginx.tmpl b/xenial-arm64-leg-nginx-ingress-controller/etc/nginx/template/nginx.tmpl new file mode 100644 index 00000000..a3953e38 --- /dev/null +++ b/xenial-arm64-leg-nginx-ingress-controller/etc/nginx/template/nginx.tmpl @@ -0,0 +1,668 @@ +{{ $all := . }} +{{ $cfg := .Cfg }} +{{ $IsIPV6Enabled := .IsIPV6Enabled }} +{{ $healthzURI := .HealthzURI }} +{{ $backends := .Backends }} +{{ $proxyHeaders := .ProxySetHeaders }} +{{ $addHeaders := .AddHeaders }} +daemon off; + +worker_processes {{ $cfg.WorkerProcesses }}; +pid /run/nginx.pid; +{{ if ne .MaxOpenFiles 0 }} +worker_rlimit_nofile {{ .MaxOpenFiles }}; +{{ end}} + +{{/* http://nginx.org/en/docs/ngx_core_module.html#worker_shutdown_timeout */}} +{{/* avoid waiting too long during a reload */}} +worker_shutdown_timeout 10s; + +events { + multi_accept on; + 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 }} + {{ range $trusted_ip := $cfg.ProxyRealIPCIDR }} + set_real_ip_from {{ $trusted_ip }}; + {{ end }} + real_ip_header proxy_protocol; + {{ else }} + {{ range $trusted_ip := $cfg.ProxyRealIPCIDR }} + set_real_ip_from {{ $trusted_ip }}; + {{ end }} + real_ip_header X-Forwarded-For; + {{ end }} + + real_ip_recursive on; + + {{/* databases used to determine the country depending on the client IP address */}} + {{/* http://nginx.org/en/docs/http/ngx_http_geoip_module.html */}} + {{/* this is require to calculate traffic for individual country using GeoIP in the status page */}} + geoip_country /etc/nginx/GeoIP.dat; + geoip_city /etc/nginx/GeoLiteCity.dat; + geoip_proxy_recursive on; + + {{ 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 }} + + sendfile on; + aio threads; + tcp_nopush on; + tcp_nodelay on; + + log_subrequest on; + + reset_timedout_connection on; + + keepalive_timeout {{ $cfg.KeepAlive }}s; + keepalive_requests {{ $cfg.KeepAliveRequests }}; + + client_header_buffer_size {{ $cfg.ClientHeaderBufferSize }}; + large_client_header_buffers {{ $cfg.LargeClientHeaderBuffers }}; + client_body_buffer_size {{ $cfg.ClientBodyBufferSize }}; + + http2_max_field_size {{ $cfg.HTTP2MaxFieldSize }}; + http2_max_header_size {{ $cfg.HTTP2MaxHeaderSize }}; + + 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 }}; + + proxy_headers_hash_max_size {{ $cfg.ProxyHeadersHashMaxSize }}; + proxy_headers_hash_bucket_size {{ $cfg.ProxyHeadersHashBucketSize }}; + + variables_hash_bucket_size {{ $cfg.VariablesHashBucketSize }}; + variables_hash_max_size {{ $cfg.VariablesHashMaxSize }}; + + underscores_in_headers {{ if $cfg.EnableUnderscoresInHeaders }}on{{ else }}off{{ end }}; + ignore_invalid_headers {{ if $cfg.IgnoreInvalidHeaders }}on{{ else }}off{{ end }}; + + include /etc/nginx/mime.types; + default_type text/html; + {{ 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 }} + + # Custom headers for response + {{ range $k, $v := $addHeaders }} + add_header {{ $k }} "{{ $v }}"; + {{ end }} + + server_tokens {{ if $cfg.ShowServerTokens }}on{{ else }}off{{ end }}; + + # disable warnings + uninitialized_variable_warn off; + + log_format upstreaminfo {{ if $cfg.LogFormatEscapeJSON }}escape=json {{ end }}'{{ buildLogFormatUpstream $cfg }}'; + + {{/* map urls that should not appear in access.log */}} + {{/* http://nginx.org/en/docs/http/ngx_http_log_module.html#access_log */}} + map $request_uri $loggable { + {{ range $reqUri := $cfg.SkipAccessLogURLs }} + {{ $reqUri }} 0;{{ end }} + default 1; + } + + {{ if $cfg.DisableAccessLog }} + access_log off; + {{ else }} + access_log /var/log/nginx/access.log upstreaminfo if=$loggable; + {{ end }} + error_log /var/log/nginx/error.log {{ $cfg.ErrorLogLevel }}; + + {{ buildResolvers $cfg.Resolver }} + + {{/* Whenever nginx proxies a request without a "Connection" header, the "Connection" header is set to "close" */}} + {{/* when making the target request. This means that you cannot simply use */}} + {{/* "proxy_set_header Connection $http_connection" for WebSocket support because in this case, the */}} + {{/* "Connection" header would be set to "" whenever the original request did not have a "Connection" header, */}} + {{/* which would mean no "Connection" header would be in the target request. Since this would deviate from */}} + {{/* 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; + } + + # trust http_x_forwarded_proto headers correctly indicate ssl offloading + map $http_x_forwarded_proto $pass_access_scheme { + default $http_x_forwarded_proto; + '' $scheme; + } + + map $http_x_forwarded_port $pass_server_port { + default $http_x_forwarded_port; + '' $server_port; + } + + {{ if $cfg.UseProxyProtocol }} + map $http_x_forwarded_for $the_real_ip { + default $http_x_forwarded_for; + '' $proxy_protocol_addr; + } + {{ else }} + map $http_x_forwarded_for $the_real_ip { + default $http_x_forwarded_for; + '' $remote_addr; + } + {{ end }} + + # map port 442 to 443 for header X-Forwarded-Port + map $pass_server_port $pass_port { + 442 443; + default $pass_server_port; + } + + # Map a response error watching the header Content-Type + map $http_accept $httpAccept { + default html; + application/json json; + application/xml xml; + text/plain text; + } + + map $httpAccept $httpReturnType { + default text/html; + json application/json; + xml application/xml; + text text/plain; + } + + # Obtain best http host + map $http_host $this_host { + default $http_host; + '' $host; + } + + map $http_x_forwarded_host $best_http_host { + default $http_x_forwarded_host; + '' $this_host; + } + + server_name_in_redirect off; + port_in_redirect off; + + 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 }}; + {{ end }} + + # allow configuring ssl session tickets + ssl_session_tickets {{ if $cfg.SSLSessionTickets }}on{{ else }}off{{ end }}; + + # slightly reduce the time-to-first-byte + ssl_buffer_size {{ $cfg.SSLBufferSize }}; + + {{ if not (empty $cfg.SSLCiphers) }} + # allow configuring custom ssl ciphers + ssl_ciphers '{{ $cfg.SSLCiphers }}'; + ssl_prefer_server_ciphers on; + {{ end }} + + {{ if not (empty $cfg.SSLDHParam) }} + # allow custom DH file http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_dhparam + ssl_dhparam {{ $cfg.SSLDHParam }}; + {{ end }} + + {{ if not $cfg.EnableDynamicTLSRecords }} + ssl_dyn_rec_size_lo 0; + {{ end }} + + ssl_ecdh_curve {{ $cfg.SSLECDHCurve }}; + + {{ if .CustomErrors }} + # Custom error pages + proxy_intercept_errors on; + {{ end }} + + {{ range $errCode := $cfg.CustomHTTPErrors }} + error_page {{ $errCode }} = @custom_{{ $errCode }};{{ end }} + + proxy_ssl_session_reuse on; + + {{ if $cfg.AllowBackendServerHeader }} + proxy_pass_header Server; + {{ end }} + + {{ range $name, $upstream := $backends }} + {{ if eq $upstream.SessionAffinity.AffinityType "cookie" }} + upstream sticky-{{ $upstream.Name }} { + sticky hash={{ $upstream.SessionAffinity.CookieSessionAffinity.Hash }} name={{ $upstream.SessionAffinity.CookieSessionAffinity.Name }} httponly; + + {{ if (gt $cfg.UpstreamKeepaliveConnections 0) }} + keepalive {{ $cfg.UpstreamKeepaliveConnections }}; + {{ end }} + + {{ range $server := $upstream.Endpoints }}server {{ $server.Address | formatIP }}:{{ $server.Port }} max_fails={{ $server.MaxFails }} fail_timeout={{ $server.FailTimeout }}; + {{ end }} + } + {{ end }} + + upstream {{ $upstream.Name }} { + # Load balance algorithm; empty for round robin, which is the default + {{ if ne $cfg.LoadBalanceAlgorithm "round_robin" }} + {{ $cfg.LoadBalanceAlgorithm }}; + {{ end }} + + {{ if (gt $cfg.UpstreamKeepaliveConnections 0) }} + keepalive {{ $cfg.UpstreamKeepaliveConnections }}; + {{ end }} + + {{ range $server := $upstream.Endpoints }}server {{ $server.Address | formatIP }}:{{ $server.Port }} max_fails={{ $server.MaxFails }} fail_timeout={{ $server.FailTimeout }}; + {{ end }} + } + {{ end }} + + {{/* build the maps that will be use to validate the Whitelist */}} + {{ range $index, $server := .Servers }} + {{ range $location := $server.Locations }} + {{ $path := buildLocation $location }} + + {{ if isLocationAllowed $location }} + {{ if gt (len $location.Whitelist.CIDR) 0 }} + geo $the_real_ip {{ buildDenyVariable (print $server.Hostname "_" $path) }} { + default 1; + + {{ range $ip := $location.Whitelist.CIDR }} + {{ $ip }} 0;{{ end }} + } + {{ end }} + {{ end }} + {{ end }} + {{ end }} + + {{/* 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 $cfg.LimitConnZoneVariable .Servers) }} + {{ $zone }} + {{ end }} + + {{ $backlogSize := .BacklogSize }} + {{ range $index, $server := .Servers }} + server { + server_name {{ $server.Hostname }}; + listen 80{{ if $cfg.UseProxyProtocol }} proxy_protocol{{ end }}{{ if eq $server.Hostname "_"}} default_server reuseport backlog={{ $backlogSize }}{{end}}; + {{ if $IsIPV6Enabled }}listen [::]:80{{ if $cfg.UseProxyProtocol }} proxy_protocol{{ end }}{{ if eq $server.Hostname "_"}} default_server reuseport backlog={{ $backlogSize }}{{ end }};{{ end }} + set $proxy_upstream_name "-"; + + {{/* Listen on 442 because port 443 is used in the TLS sni server */}} + {{/* This listener must always have proxy_protocol enabled, because the SNI listener forwards on source IP info in it. */}} + {{ if not (empty $server.SSLCertificate) }}listen 442 proxy_protocol{{ if eq $server.Hostname "_"}} default_server reuseport backlog={{ $backlogSize }}{{end}} ssl {{ if $cfg.UseHTTP2 }}http2{{ end }}; + {{ if $IsIPV6Enabled }}{{ if not (empty $server.SSLCertificate) }}listen [::]:442 proxy_protocol{{ end }} {{ if eq $server.Hostname "_"}} default_server reuseport backlog={{ $backlogSize }}{{end}} ssl {{ if $cfg.UseHTTP2 }}http2{{ end }};{{ 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 (not (empty $server.SSLCertificate)) $cfg.HSTS) }} + more_set_headers "Strict-Transport-Security: max-age={{ $cfg.HSTSMaxAge }}{{ if $cfg.HSTSIncludeSubdomains }}; includeSubDomains{{ end }};{{ if $cfg.HSTSPreload }} preload{{ end }}"; + {{ 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 }} + {{ $authPath := buildAuthLocation $location }} + + {{ if not (empty $location.CertificateAuth.AuthSSLCert.CAFileName) }} + # PEM sha: {{ $location.CertificateAuth.AuthSSLCert.PemSHA }} + ssl_client_certificate {{ $location.CertificateAuth.AuthSSLCert.CAFileName }}; + ssl_verify_client on; + ssl_verify_depth {{ $location.CertificateAuth.ValidationDepth }}; + {{ end }} + + {{ if not (empty $location.Redirect.AppRoot)}} + if ($uri = /) { + return 302 {{ $location.Redirect.AppRoot }}; + } + {{ end }} + + {{ if not (empty $authPath) }} + location = {{ $authPath }} { + internal; + set $proxy_upstream_name "internal"; + + {{ if not $location.ExternalAuth.SendBody }} + proxy_pass_request_body off; + proxy_set_header Content-Length ""; + {{ end }} + {{ if not (empty $location.ExternalAuth.Method) }} + proxy_method {{ $location.ExternalAuth.Method }}; + proxy_set_header X-Original-URI $request_uri; + proxy_set_header X-Scheme $pass_access_scheme; + {{ end }} + proxy_pass_request_headers on; + proxy_set_header Host {{ $location.ExternalAuth.Host }}; + proxy_ssl_server_name on; + + client_max_body_size "{{ $location.Proxy.BodySize }}"; + + + set $target {{ $location.ExternalAuth.URL }}; + proxy_pass $target; + } + {{ end }} + + location {{ $path }} { + set $proxy_upstream_name "{{ buildUpstreamName $server.Hostname $backends $location }}"; + + {{ if (or $location.Redirect.ForceSSLRedirect (and (not (empty $server.SSLCertificate)) $location.Redirect.SSLRedirect)) }} + # enforce ssl on server side + if ($pass_access_scheme = http) { + return 301 https://$best_http_host$request_uri; + } + {{ end }} + + {{ if isLocationAllowed $location }} + {{ if gt (len $location.Whitelist.CIDR) 0 }} + if ({{ buildDenyVariable (print $server.Hostname "_" $path) }}) { + return 403; + } + {{ end }} + + port_in_redirect {{ if $location.UsePortInRedirects }}on{{ else }}off{{ end }}; + + {{ if not (empty $authPath) }} + # this location requires authentication + auth_request {{ $authPath }}; + {{- range $idx, $line := buildAuthResponseHeaders $location }} + {{ $line }} + {{- end }} + {{ end }} + + {{ if not (empty $location.ExternalAuth.SigninURL) }} + error_page 401 = {{ $location.ExternalAuth.SigninURL }}; + {{ end }} + + + {{/* if the location contains a rate limit annotation, create one */}} + {{ $limits := buildRateLimit $location }} + {{ range $limit := $limits }} + {{ $limit }}{{ end }} + + {{ if $location.BasicDigestAuth.Secured }} + {{ if eq $location.BasicDigestAuth.Type "basic" }} + auth_basic "{{ $location.BasicDigestAuth.Realm }}"; + auth_basic_user_file {{ $location.BasicDigestAuth.File }}; + {{ else }} + auth_digest "{{ $location.BasicDigestAuth.Realm }}"; + auth_digest_user_file {{ $location.BasicDigestAuth.File }}; + {{ end }} + proxy_set_header Authorization ""; + {{ end }} + + {{ if $location.EnableCORS }} + {{ template "CORS" }} + {{ end }} + + client_max_body_size "{{ $location.Proxy.BodySize }}"; + + proxy_set_header Host $best_http_host; + + # Pass the extracted client certificate to the backend + {{ if not (empty $location.CertificateAuth.AuthSSLCert.CAFileName) }} + proxy_set_header ssl-client-cert $ssl_client_cert; + {{ end }} + + # Allow websocket connections + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + + proxy_set_header X-Real-IP $the_real_ip; + proxy_set_header X-Forwarded-For $the_real_ip; + proxy_set_header X-Forwarded-Host $best_http_host; + proxy_set_header X-Forwarded-Port $pass_port; + proxy_set_header X-Forwarded-Proto $pass_access_scheme; + proxy_set_header X-Original-URI $request_uri; + proxy_set_header X-Scheme $pass_access_scheme; + + # mitigate HTTPoxy Vulnerability + # https://www.nginx.com/blog/mitigating-the-httpoxy-vulnerability-with-nginx/ + proxy_set_header Proxy ""; + + # Custom headers to proxied server + {{ range $k, $v := $proxyHeaders }} + proxy_set_header {{ $k }} "{{ $v }}"; + {{ end }} + + proxy_connect_timeout {{ $location.Proxy.ConnectTimeout }}s; + proxy_send_timeout {{ $location.Proxy.SendTimeout }}s; + proxy_read_timeout {{ $location.Proxy.ReadTimeout }}s; + + proxy_redirect off; + proxy_buffering off; + proxy_buffer_size "{{ $location.Proxy.BufferSize }}"; + proxy_buffers 4 "{{ $location.Proxy.BufferSize }}"; + + proxy_http_version 1.1; + + proxy_cookie_domain {{ $location.Proxy.CookieDomain }}; + proxy_cookie_path {{ $location.Proxy.CookiePath }}; + + # In case of errors try the next upstream server before returning an error + proxy_next_upstream {{ buildNextUpstream $location.Proxy.NextUpstream }}{{ if $cfg.RetryNonIdempotent }} non_idempotent{{ end }}; + + {{/* rewrite only works if the content is not compressed */}} + {{ if $location.Redirect.AddBaseURL }} + proxy_set_header Accept-Encoding ""; + {{ end }} + + {{/* Add any additional configuration defined */}} + {{ $location.ConfigurationSnippet }} + + {{ buildProxyPass $server.Hostname $backends $location }} + {{ else }} + #{{ $location.Denied }} + return 503; + {{ end }} + } + {{ end }} + + {{ if eq $server.Hostname "_" }} + # health checks in cloud providers require the use of port 80 + location {{ $healthzURI }} { + access_log off; + return 200; + } + + # this is required to avoid error if nginx is being monitored + # with an external software (like sysdig) + location /nginx_status { + allow 127.0.0.1; + {{ if $IsIPV6Enabled }}allow ::1;{{ end }} + deny all; + + access_log off; + stub_status on; + } + {{ end }} + + {{ template "CUSTOM_ERRORS" $all }} + } + + {{ 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. + # Changing this value requires a change in: + # https://github.com/kubernetes/ingress/blob/master/controllers/nginx/pkg/cmd/controller/nginx.go + listen 18080 default_server reuseport backlog={{ .BacklogSize }}; + {{ if $IsIPV6Enabled }}listen [::]:18080 default_server reuseport backlog={{ .BacklogSize }};{{ end }} + set $proxy_upstream_name "-"; + + location {{ $healthzURI }} { + access_log off; + return 200; + } + + location /nginx_status { + set $proxy_upstream_name "internal"; + + {{ if $cfg.EnableVtsStatus }} + vhost_traffic_status_display; + vhost_traffic_status_display_format html; + {{ else }} + access_log off; + stub_status on; + {{ end }} + } + + # this location is used to extract nginx metrics + # using prometheus. + # TODO: enable extraction for vts module. + location /internal_nginx_status { + set $proxy_upstream_name "internal"; + + allow 127.0.0.1; + {{ if not $cfg.DisableIpv6 }}allow ::1;{{ end }} + deny all; + + access_log off; + stub_status on; + } + + location / { + set $proxy_upstream_name "upstream-default-backend"; + proxy_pass http://upstream-default-backend; + } + {{ template "CUSTOM_ERRORS" $all }} + } + + # default server for services without endpoints + server { + listen 8181; + set $proxy_upstream_name "-"; + + location / { + {{ if .CustomErrors }} + include /etc/nginx/fastcgi_params; + fastcgi_param HTTP_X_Code 503; + fastcgi_param HTTP_X_Format $http_accept; + fastcgi_param HTTP_X_Endpoints {{ .DefaultBackendEndpoints }}; + fastcgi_pass unix:/var/run/go-fastcgi.sock; + {{ else }} + return 503; + {{ end }} + } + } +} + +stream { + log_format log_stream {{ $cfg.LogFormatStream }}; + + {{ if $cfg.DisableAccessLog }} + access_log off; + {{ else }} + access_log /var/log/nginx/access.log log_stream; + {{ end }} + + error_log /var/log/nginx/error.log; + + # TCP services + {{ range $i, $tcpServer := .TCPBackends }} + upstream tcp-{{ $tcpServer.Port }}-{{ $tcpServer.Backend.Namespace }}-{{ $tcpServer.Backend.Name }}-{{ $tcpServer.Backend.Port }} { + {{ range $j, $endpoint := $tcpServer.Endpoints }} + server {{ $endpoint.Address }}:{{ $endpoint.Port }}; + {{ end }} + } + server { + listen {{ $tcpServer.Port }}{{ if $tcpServer.Backend.UseProxyProtocol }} proxy_protocol{{ end }}; + {{ if $IsIPV6Enabled }}listen [::]:{{ $tcpServer.Port }}{{ if $tcpServer.Backend.UseProxyProtocol }} proxy_protocol{{ end }};{{ end }} + proxy_timeout {{ $cfg.ProxyStreamTimeout }}; + proxy_pass tcp-{{ $tcpServer.Port }}-{{ $tcpServer.Backend.Namespace }}-{{ $tcpServer.Backend.Name }}-{{ $tcpServer.Backend.Port }}; + } + + {{ end }} + + # UDP services + {{ range $i, $udpServer := .UDPBackends }} + upstream udp-{{ $udpServer.Port }}-{{ $udpServer.Backend.Namespace }}-{{ $udpServer.Backend.Name }}-{{ $udpServer.Backend.Port }} { + {{ range $j, $endpoint := $udpServer.Endpoints }} + server {{ $endpoint.Address }}:{{ $endpoint.Port }}; + {{ end }} + } + + server { + listen {{ $udpServer.Port }} udp; + {{ if $IsIPV6Enabled }}listen [::]:{{ $udpServer.Port }} udp;{{ end }} + proxy_responses 1; + proxy_timeout {{ $cfg.ProxyStreamTimeout }}; + proxy_pass udp-{{ $udpServer.Port }}-{{ $udpServer.Backend.Namespace }}-{{ $udpServer.Backend.Name }}-{{ $udpServer.Backend.Port }}; + } + {{ end }} +} + +{{/* definition of templates to avoid repetitions */}} +{{ define "CUSTOM_ERRORS" }} + {{ $defaultBackendEndpoints := .DefaultBackendEndpoints }} + {{ range $errCode := .Cfg.CustomHTTPErrors }} + location @custom_{{ $errCode }} { + internal; + include /etc/nginx/fastcgi_params; + fastcgi_param HTTP_X_Code {{ $errCode }}; + fastcgi_param HTTP_X_Format $http_accept; + fastcgi_param HTTP_X_Endpoints {{ $defaultBackendEndpoints }}; + fastcgi_pass unix:/var/run/go-fastcgi.sock; + } + {{ end }} +{{ end }} + +{{/* CORS support from https://michielkalkman.com/snippets/nginx-cors-open-configuration.html */}} +{{ define "CORS" }} + if ($request_method = 'OPTIONS') { + add_header 'Access-Control-Allow-Origin' '*'; + # + # Om nom nom cookies + # + add_header 'Access-Control-Allow-Credentials' 'true'; + add_header 'Access-Control-Allow-Methods' 'GET, PUT, POST, DELETE, OPTIONS'; + # + # Custom headers and headers various browsers *should* be OK with but aren't + # + add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization'; + # + # Tell client that this pre-flight info is valid for 20 days + # + add_header 'Access-Control-Max-Age' 1728000; + add_header 'Content-Type' 'text/plain charset=UTF-8'; + add_header 'Content-Length' 0; + return 204; + } + set $cors_method 0; + if ($request_method = 'GET') { + set $cors_method 1; + } + if ($request_method = 'PUT') { + set $cors_method 1; + } + if ($request_method = 'POST') { + set $cors_method 1; + } + if ($request_method = 'DELETE') { + set $cors_method 1; + } + + if ($cors_method = 1) { + add_header 'Access-Control-Allow-Origin' '*' always; + add_header 'Access-Control-Allow-Credentials' 'true'; + add_header 'Access-Control-Allow-Methods' 'GET, PUT, POST, DELETE, OPTIONS'; + add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization'; + } +{{ end }} diff --git a/xenial-arm64-leg-nginx-ingress-controller/ingress-controller/clean-nginx-conf.sh b/xenial-arm64-leg-nginx-ingress-controller/ingress-controller/clean-nginx-conf.sh new file mode 100755 index 00000000..53662152 --- /dev/null +++ b/xenial-arm64-leg-nginx-ingress-controller/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;}' |