# Copyright 2022 Google LLC
#
# 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
#
#     https://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: apigee-envoyfilter-1.11
  namespace: "apigee"
  labels:
    apigee.cloud.google.com/platform: apigee
data:
  envoyfilter-1.11.yaml: |-
    # for 1.11 asm
    apiVersion: networking.istio.io/v1alpha3
    kind: EnvoyFilter
    metadata:
      name: apigee-envoyfilter-1-11
      namespace: 'apigee'
    spec:
      workloadSelector:
        labels:
          app: apigee-ingressgateway
      configPatches:
      - applyTo: NETWORK_FILTER
        match:
          listener:
            filterChain:
              filter:
                name: "envoy.filters.network.http_connection_manager"
          proxy:
            proxyVersion: ^1\.11.*
        patch:
          operation: MERGE
          value:
            typed_config:
              "@type": "type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager"
              server_header_transformation: PASS_THROUGH
      - applyTo: ROUTE_CONFIGURATION
        patch:
          operation: MERGE
          value:
            # https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route.proto#envoy-v3-api-msg-config-route-v3-routeconfiguration
            request_headers_to_add:
            - header:
                key: 'x-apigee-tls-server-name'
                value: '%REQ(:AUTHORITY)%'
            - header:
                key: 'x-apigee-tls-cipher'
                value: '%DOWNSTREAM_TLS_CIPHER%'
            - header:
                key: 'x-apigee-tls-protocol'
                value: '%DOWNSTREAM_TLS_VERSION%'
            - header:
                key: 'x-apigee-tls-session-id'
                value: '%DOWNSTREAM_TLS_SESSION_ID%'
            - header:
                key: 'x-apigee-tls-client-cert-fingerprint'
                value: '%DOWNSTREAM_PEER_FINGERPRINT_256%'
            - header:
                key: 'x-apigee-tls-client-cert-serial'
                value: '%DOWNSTREAM_PEER_SERIAL%'
            - header:
                key: 'x-apigee-tls-client-raw-cert'
                value: '%DOWNSTREAM_PEER_CERT%'
            - header:
                key: 'x-apigee-tls-client-i-dn'
                value: '%DOWNSTREAM_PEER_ISSUER%'
            - header:
                key: 'x-apigee-tls-client-s-dn'
                value: '%DOWNSTREAM_PEER_SUBJECT%'
            - header:
                key: 'x-apigee-client-connection'
                value: '%DOWNSTREAM_REMOTE_ADDRESS%'
      - applyTo: HTTP_FILTER
        match:
          context: GATEWAY
          proxy:
            proxyVersion: ^1\.11.*
          listener:
            filterChain:
              filter:
                name: "envoy.filters.network.http_connection_manager"
                subFilter:
                  name: "envoy.filters.http.router"
        patch:
          operation: INSERT_BEFORE
          value:
            name: envoy.lua
            typed_config:
              "@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua"
              inlineCode: |
                function envoy_on_request(request_handle)
                  -- Sanitize and remove any x-apigee and x-envoy headers from the request.
                  toremove = {}
                  for k, v in pairs(request_handle:headers()) do
                    lowerkey = string.lower(k)
                    if string.find(lowerkey, "x-apigee") ~= nil or string.find(lowerkey, "x-envoy") ~= nil then
                      toremove[k] = ""
                    end
                  end
                  for k,v in pairs(toremove) do
                    request_handle:headers():remove(k)
                  end

                  -- Add X-APIGEE-MESSAGE-ID and handle Gooogle LB health check requests.
                  request_handle:headers():replace("X-APIGEE-MESSAGE-ID", request_handle:headers():get("X-REQUEST-ID"))
                  user_agent = request_handle:headers():get("USER-AGENT")
                  if user_agent ~= nil and (user_agent:sub(1, 8) == "GoogleHC"
                    or user_agent == "GoogleStackdriverMonitoring-UptimeChecks(https://cloud.google.com/monitoring)") then
                    p = request_handle:headers():get(":PATH")
                    if p == "/healthz/ingress" then
                      request_handle:respond({[":status"] = "200"}, "Apigee Ingress is healthy")
                    end
                    if p:sub(1,8) == "/healthz" then
                     request_handle:headers():add("x-apigee-heartbeat", "true")
                     request_handle:headers():replace(":PATH", p:sub(9,-1))
                    end
                  end
                end

                -- Sanitize and remove any x-apigee and x-envoy headers from responses.
                function envoy_on_response(response_handle)
                  toremove = {}
                  for k, v in pairs(response_handle:headers()) do
                    lowerkey = string.lower(k)
                    if string.find(lowerkey, "x-apigee") ~= nil or string.find(lowerkey, "x-envoy") ~= nil then
                      normalized_key = string.gsub(string.gsub(lowerkey, "%.", "_"), "%-", "_")
                      response_handle:streamInfo():dynamicMetadata():set("envoy.lua",normalized_key,v)
                      toremove[k] = ""
                    end
                  end
                  for k,v in pairs(toremove) do
                    response_handle:headers():remove(k)
                  end
                end
    ---
