#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.
#

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-nginx
  labels:
{{ include "openwhisk.label_boilerplate" . | indent 4 }}
data:
  nginx.conf: |
    worker_processes {{ .Values.nginx.workerProcesses }};
    worker_rlimit_nofile 4096;

    events {
      worker_connections  4096;
    }

    http {
      client_max_body_size 50M;

      rewrite_log on;
      # change log format to display the upstream information
      log_format combined-upstream '$remote_addr - $remote_user [$time_local] '
          '[#tid_$request_id] $request $status $body_bytes_sent '
          '$http_referer $http_user_agent $upstream_addr';
      access_log /logs/nginx_access.log combined-upstream;
      error_log /logs/nginx_error.log error;

      # needed to enable keepalive to upstream controllers
      proxy_http_version 1.1;
      proxy_set_header Connection "";

      upstream controllers {
         # Mark the controller as unavailable after fail_timeout seconds, to not get any requests during restart.
         # Otherwise, nginx would dispatch requests when the container is up, but the backend in the container not.
         # From the docs:
         #  "normally, requests with a non-idempotent method (POST, LOCK, PATCH) are not passed to
         #   the next server if a request has been sent to an upstream server"
         server {{ include "openwhisk.controller_host" . }}:{{ .Values.controller.port }} fail_timeout=60s;

         keepalive 512;
      }

      server {
        listen 80;
{{- if or (eq .Values.whisk.ingress.type "NodePort") (eq .Values.whisk.ingress.type "LoadBalancer") }}
        listen 443 default ssl;
{{- end }}

        # match namespace, note while OpenWhisk allows a richer character set for a
        # namespace, not all those characters are permitted in the (sub)domain name;
        # if namespace does not match, no vanity URL rewriting takes place.
        server_name ~^(?<namespace>[0-9a-zA-Z-]+)\.{{ .Values.whisk.ingress.apiHostName }}$;

{{- if or (eq .Values.whisk.ingress.type "NodePort") (eq .Values.whisk.ingress.type "LoadBalancer") }}
        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  10m;
        ssl_certificate      /etc/nginx/certs/tls.crt;
        ssl_certificate_key  /etc/nginx/certs/tls.key;
        {{- if .Values.nginx.certificate.external }}
        {{- if ne .Values.nginx.certificate.sslPassword "" }}
        ssl_password_file "/etc/nginx/certs/sslPassword";
        {{- end }}
        {{- end }}
        ssl_verify_client off;
        ssl_protocols        TLSv1.2;
        ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256;
        ssl_prefer_server_ciphers on;
        proxy_ssl_session_reuse on;
        proxy_ssl_verify off;
{{- end }}

        # Hack to convince nginx to dynamically resolve the dns entries.
        resolver {{ .Values.k8s.dns }};
{{- if or (eq .Values.whisk.ingress.type "NodePort") (eq .Values.whisk.ingress.type "LoadBalancer") }}
        set $apigw {{ include "openwhisk.apigw_host" . }};
{{ if or .Values.metrics.prometheusEnabled .Values.metrics.userMetricsEnabled }}
        set $grafana {{ include "openwhisk.grafana_host" . }};
{{- end }}
{{- end }}

{{- if or (eq .Values.whisk.ingress.type "NodePort") (eq .Values.whisk.ingress.type "LoadBalancer") }}
        location /api/v1/web {
            if ($namespace) {
                rewrite    /(.*) /api/v1/web/${namespace}/$1 break;
            }
            proxy_pass http://controllers;
            proxy_read_timeout 75s; # 70+5 additional seconds to allow controller to terminate request
        }

        location /api/v1 {
            proxy_pass http://controllers;
            proxy_read_timeout 75s; # 70+5 additional seconds to allow controller to terminate request
        }

        location /api {
            proxy_pass http://$apigw:{{ .Values.apigw.mgmtPort }};
        }

        location /v1/health-check {
            proxy_pass http://$apigw:{{ .Values.apigw.apiPort }};
        }

        location /v2 {
            proxy_pass http://$apigw:{{ .Values.apigw.apiPort }};
        }

{{ if or .Values.metrics.prometheusEnabled .Values.metrics.userMetricsEnabled }}
        location /monitoring {
            proxy_pass http://$grafana:{{ .Values.grafana.port }};
        }
{{- end }}
{{- end }}
        location / {
            if ($namespace) {
              rewrite    /(.*) /api/v1/web/${namespace}/$1 break;
            }
            proxy_pass http://controllers;
            proxy_read_timeout 75s; # 70+5 additional seconds to allow controller to terminate request
        }

        location /blackbox.tar.gz {
            return 301 https://github.com/apache/openwhisk-runtime-docker/releases/download/sdk%400.1.0/blackbox-0.1.0.tar.gz;
        }
        # leaving this for a while for clients out there to update to the new endpoint
        location /blackbox-0.1.0.tar.gz {
            return 301 /blackbox.tar.gz;
        }

        location /OpenWhiskIOSStarterApp.zip {
            return 301 https://github.com/openwhisk/openwhisk-client-swift/releases/download/0.2.3/starterapp-0.2.3.zip;
        }

        # redirect requests for specific binaries to the matching one from the latest openwhisk-cli release.
        location /cli/go/download/linux/amd64 {
            return 301 https://github.com/apache/openwhisk-cli/releases/download/latest/OpenWhisk_CLI-latest-linux-amd64.tgz;
        }
        location /cli/go/download/linux/386 {
            return 301 https://github.com/apache/openwhisk-cli/releases/download/latest/OpenWhisk_CLI-latest-linux-386.tgz;
        }
        location /cli/go/download/mac/amd64 {
            return 301 https://github.com/apache/openwhisk-cli/releases/download/latest/OpenWhisk_CLI-latest-mac-amd64.zip;
        }
        location /cli/go/download/mac/386 {
            return 301 https://github.com/apache/openwhisk-cli/releases/download/latest/OpenWhisk_CLI-latest-mac-386.zip;
        }
        location /cli/go/download/windows/amd64 {
            return 301 https://github.com/apache/openwhisk-cli/releases/download/latest/OpenWhisk_CLI-latest-windows-amd64.zip;
        }
        location /cli/go/download/windows/386 {
            return 301 https://github.com/apache/openwhisk-cli/releases/download/latest/OpenWhisk_CLI-latest-windows-386.zip;
        }

        # redirect top-level cli downloads to the latest openwhisk-cli release.
        location /cli/go/download {
            return 301 https://github.com/apache/openwhisk-cli/releases/latest;
        }
      }
    }
