#
  # Copyright 2020, 2021 ZUP IT SERVICOS EM TECNOLOGIA E INOVACAO SA
  #
  # 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.
#
apiVersion: v1
data:
  envoy.yaml: |-
    static_resources:
      listeners:
      - address:
          socket_address:
            address: 0.0.0.0
            port_value: 80
        filter_chains:
        - filters:
          - name: envoy.http_connection_manager
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
              codec_type: auto
              stat_prefix: ingress_http
              access_log:
              - name: envoy.access_loggers.file
                typed_config:
                  "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
                  path: "/dev/stdout"
              route_config:
                name: local_route
                virtual_hosts:
                - name: backend
                  domains:
                  - "*"
                  {{ if .Values.cors.enabled }}
                  cors:
                    allow_origin_string_match:
                    {{- range $host := .Values.cors.hosts }}
                    - exact: "{{ $host }}"
                    {{- end }}
                    allow_methods: "GET, POST, PUT, DELETE, PATCH, OPTIONS"
                    allow_headers: "Authorization,x-circle-id,x-workspace-id,DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range"
                  {{- end}}
                  routes:
                  {{ if .Values.moove.enabled }}
                  - match:
                      prefix: "/moove/"
                    route:
                      prefix_rewrite: "/"
                      cluster: charlescd-moove
                      auto_host_rewrite: true

                  {{- end}}
                  {{ if .Values.circlematcher.enabled }}
                  - match:
                      prefix: "/charlescd-circle-matcher/"
                    route:
                      prefix_rewrite: "/"
                      cluster: charlescd-circle-matcher
                      auto_host_rewrite: true
                    typed_per_filter_config:
                      envoy.filters.http.lua:
                        "@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute
                        disabled: true
                  {{- end}}
                  {{ if .Values.keycloak.enabled }}
                  - match:
                      prefix: "/keycloak"
                    route:
                      cluster: {{ .Release.Name }}-keycloak-http
                    typed_per_filter_config:
                      envoy.filters.http.lua:
                        "@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute
                        disabled: true
                  {{- end}}
                  {{ if .Values.compass.enabled }}
                  - match:
                      prefix: "/compass/"
                    route:
                      prefix_rewrite: "/"
                      cluster: charlescd-compass
                      auto_host_rewrite: true
                    typed_per_filter_config:
                      envoy.filters.http.lua:
                        "@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute
                        disabled: true
                  {{- end}}
                  {{ if .Values.hermes.enabled }}
                  - match:
                      prefix: "/hermes/"
                    route:
                      prefix_rewrite: "/"
                      cluster: charlescd-hermes
                      auto_host_rewrite: true
                    typed_per_filter_config:
                      envoy.filters.http.lua:
                        "@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute
                        disabled: true
                  {{- end}}
                  {{ if .Values.gate.enabled }}
                  - match:
                      prefix: "/gate/"
                    route:
                      prefix_rewrite: "/"
                      cluster: charlescd-gate
                      auto_host_rewrite: true
                  {{- end}}
                  {{ if .Values.ui.enabled }}
                  - match:
                      prefix: "/"
                    route:
                      cluster: charlescd-ui
                      auto_host_rewrite: true
                    typed_per_filter_config:
                      envoy.filters.http.lua:
                        "@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute
                        disabled: true
                  {{- end}}
              http_filters:
              {{ if .Values.cors.enabled }}
              - name: envoy.filters.http.cors
                typed_config: {}
              {{- end}}
              - name: envoy.filters.http.lua
                typed_config:
                  "@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
                  inline_code: |
                    function envoy_on_request(request_handle)
                      local user_token = request_handle:headers():get("authorization")
                      local system_token = request_handle:headers():get("x-charles-token")
                      if user_token ~= nil and system_token ~= nil then
                        request_handle:logInfo("LUASCRIPT:DOUBLE_TOKEN_HEADER")
                        request_handle:respond({
                          [":status"] = "400"
                        }, "You must not use Authorization and X-Charles-Token on the same request")
                      end
                    end
              - name: envoy.filters.http.lua
                typed_config:
                  "@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
                  inline_code: |
                    function envoy_on_request(request_handle)
                      local user_token = request_handle:headers():get("authorization")
                      if user_token ~= nil then
                        local request = require("luajit-init")
                        local response = request.send(
                          "{{ .Values.idm.protocol }}://{{ .Values.idm.endpoint }}{{ .Values.idm.path }}",
                          {
                            headers = {
                              authorization = user_token
                            }
                          }
                        )
                        request_handle:logInfo("LUASCRIPT:CHECK_TOKEN")
                        request_handle:logInfo("IDM user validation response: "..response.code)
                        if response.code ~= 200 then
                          request_handle:respond({
                            [":status"] = response.code
                          }, response.body)
                        end
                      end
                    end
              - name: envoy.filters.http.lua
                typed_config:
                  "@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
                  inline_code: |
                    function envoy_on_request(request_handle)
                      request_handle:logInfo("LUASCRIPT:AUTHORIZATION_SERVICE")
                      local user_token = request_handle:headers():get("authorization")
                      local system_token = request_handle:headers():get("x-charles-token")
                      local workspace_id = request_handle:headers():get("x-workspace-id")
                      local method = request_handle:headers():get(":method")

                      local url_encoded = request_handle:headers():get(":path")
                      url_encoded = string.gsub(url_encoded, "+", " ")
                      local url_decoded = string.gsub(url_encoded, "%%(%x%x)", function (hex) return string.char(tonumber(hex,16)) end)
                      local path_without_params = url_decoded:match("([^,]+)?([^,]+)")

                      local path = ""

                      if path_without_params == nil then
                        path = url_decoded
                      else
                        path = path_without_params
                      end

                      local headers, body = request_handle:httpCall(
                      "charlescd-gate",
                      {
                        [":method"] = "POST",
                        [":path"] = "/api/v1/authorize",
                        [":authority"] = "charlescd-gate",
                        ["content-type"] = "application/json",
                        ["authorization"] = user_token,
                        ["x-charles-token"] = system_token,
                        ["x-workspace-id"] = workspace_id
                      },
                      "{\"path\": \"" ..path.. "\", \"method\": \"" ..method.. "\"}",
                      2000,
                      false
                      )

                      request_handle:logInfo("Authorization service response status: "..headers[":status"])
                      if headers[":status"] ~= "204" then
                        request_handle:logInfo("Denying request ["..method.."] "..path)
                        request_handle:respond({
                          [":status"] = 403
                        }, "Forbidden")
                      end
                    end
              - name: envoy.filters.http.router
                typed_config: {}

      clusters:
      {{ if .Values.ui.enabled }}
      - name: charlescd-ui
        connect_timeout: 0.25s
        type: strict_dns
        lb_policy: round_robin
        http_protocol_options: {}
        load_assignment:
          cluster_name: charlescd-ui
          endpoints:
          - lb_endpoints:
            - endpoint:
                address:
                  socket_address:
                    address: charlescd-ui
                    port_value: 3000
      {{- end}}
      {{ if .Values.moove.enabled }}
      - name: charlescd-moove
        connect_timeout: 0.25s
        type: strict_dns
        lb_policy: round_robin
        http_protocol_options: {}
        load_assignment:
          cluster_name: charlescd-moove
          endpoints:
          - lb_endpoints:
            - endpoint:
                address:
                  socket_address:
                    address: charlescd-moove
                    port_value: 8080
      {{- end}}
      {{ if .Values.octopipe.enabled }}
      - name: charlescd-octopipe
        connect_timeout: 0.25s
        type: strict_dns
        lb_policy: round_robin
        http_protocol_options: {}
        load_assignment:
          cluster_name: charlescd-octopipe
          endpoints:
          - lb_endpoints:
            - endpoint:
                address:
                  socket_address:
                    address: charlescd-octopipe
                    port_value: 8080
      {{- end}}
      {{ if .Values.circlematcher.enabled }}
      - name: charlescd-circle-matcher
        connect_timeout: 0.25s
        type: strict_dns
        lb_policy: round_robin
        http_protocol_options: {}
        load_assignment:
          cluster_name: charlescd-circle-matcher
          endpoints:
          - lb_endpoints:
            - endpoint:
                address:
                  socket_address:
                    address: charlescd-circle-matcher
                    port_value: 8080
      {{- end}}
      - name: {{ .Release.Name }}-keycloak-http
        connect_timeout: 2.00s
        type: strict_dns
        lb_policy: round_robin
        http_protocol_options: {}
        load_assignment:
          cluster_name: {{ .Release.Name }}-keycloak-http
          endpoints:
          - lb_endpoints:
            - endpoint:
                address:
                  socket_address:
                    address: {{ .Values.idm.endpoint }}
                    port_value: {{ .Values.idm.port }}
      {{ if .Values.compass.enabled }}
      - name: charlescd-compass
        connect_timeout: 0.25s
        type: strict_dns
        lb_policy: round_robin
        http_protocol_options: {}
        load_assignment:
          cluster_name: charlescd-compass
          endpoints:
          - lb_endpoints:
            - endpoint:
                address:
                  socket_address:
                    address: charlescd-compass
                    port_value: 8080
      {{- end}}
      {{ if .Values.hermes.enabled }}
      - name: charlescd-hermes
        connect_timeout: 0.25s
        type: strict_dns
        lb_policy: round_robin
        http_protocol_options: {}
        load_assignment:
          cluster_name: charlescd-hermes
          endpoints:
          - lb_endpoints:
            - endpoint:
                address:
                  socket_address:
                    address: charlescd-hermes
                    port_value: 8080
      {{- end}}
      {{ if .Values.gate.enabled }}
      - name: charlescd-gate
        connect_timeout: 0.25s
        type: strict_dns
        lb_policy: round_robin
        http_protocol_options: {}
        load_assignment:
          cluster_name: charlescd-gate
          endpoints:
          - lb_endpoints:
            - endpoint:
                address:
                  socket_address:
                    address: charlescd-gate
                    port_value: 8080
      {{- end}}
    admin:
      access_log_path: "/dev/stdout"
      address:
        socket_address:
          address: 0.0.0.0
          port_value: 8001
kind: ConfigMap
metadata:
  name: confenvoy
