apiVersion: v1
kind: ServiceAccount
metadata:
  name: envoy-gateway
  namespace: juwan

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: envoy-config
  namespace: juwan
data:
  envoy.yaml: |
    static_resources:
      listeners:
        - name: ingress_http
          address:
            socket_address:
              address: "::"
              port_value: 8080
              ipv4_compat: true
          filter_chains:
            - filters:
                - name: envoy.filters.network.http_connection_manager
                  typed_config:
                    "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
                    stat_prefix: ingress_http
                    codec_type: AUTO
                    generate_request_id: true
                    use_remote_address: true
                    xff_num_trusted_hops: 1
                    route_config:
                      name: local_route
                      virtual_hosts:
                        - name: juwan_services
                          domains: ["*"]
                          routes:
                            - match:
                                path: /healthz
                              direct_response:
                                status: 200
                                body:
                                  inline_string: ok
                              typed_per_filter_config:
                                envoy.filters.http.ext_authz:
                                  "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
                                  disabled: true

                            - match:
                                path: /api/v1/auth/login
                              route:
                                cluster: user_api_cluster
                                timeout: 30s
                                rate_limits:
                                  - actions:
                                      - generic_key:
                                          descriptor_value: login
                                      - remote_address: {}
                              typed_per_filter_config:
                                envoy.filters.http.ext_authz:
                                  "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
                                  disabled: true

                            - match:
                                path: /api/v1/auth/register
                              route:
                                cluster: user_api_cluster
                                timeout: 30s
                                rate_limits:
                                  - actions:
                                      - generic_key:
                                          descriptor_value: register
                                      - remote_address: {}
                              typed_per_filter_config:
                                envoy.filters.http.ext_authz:
                                  "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
                                  disabled: true

                            - match:
                                path: /api/v1/auth/reset-password
                              route:
                                cluster: user_api_cluster
                                timeout: 30s
                              typed_per_filter_config:
                                envoy.filters.http.ext_authz:
                                  "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
                                  disabled: true

                            - match:
                                path: /api/v1/auth/forgot-password/send
                              route:
                                cluster: email_api_cluster
                                timeout: 30s
                                rate_limits:
                                  - actions:
                                      - generic_key:
                                          descriptor_value: forgot_password_send
                                      - remote_address: {}
                              typed_per_filter_config:
                                envoy.filters.http.ext_authz:
                                  "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
                                  disabled: true

                            - match:
                                path: /api/v1/email/verification-code/send
                              route:
                                cluster: email_api_cluster
                                timeout: 30s
                                rate_limits:
                                  - actions:
                                      - generic_key:
                                          descriptor_value: verify_code_send
                                      - remote_address: {}
                              typed_per_filter_config:
                                envoy.filters.http.ext_authz:
                                  "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
                                  disabled: true

                            - match:
                                prefix: /api/v1/games
                                headers:
                                  - name: ":method"
                                    exact_match: GET
                              route:
                                cluster: game_api_cluster
                                timeout: 30s
                              typed_per_filter_config:
                                envoy.filters.http.ext_authz:
                                  "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
                                  disabled: true

                            - match:
                                path: /api/v1/players/me
                                headers:
                                  - name: ":method"
                                    exact_match: GET
                              route:
                                cluster: player_api_cluster
                                timeout: 30s

                            - match:
                                prefix: /api/v1/players
                                headers:
                                  - name: ":method"
                                    exact_match: GET
                              route:
                                cluster: player_api_cluster
                                timeout: 30s
                              typed_per_filter_config:
                                envoy.filters.http.ext_authz:
                                  "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
                                  disabled: true

                            - match:
                                prefix: /api/v1/services
                                headers:
                                  - name: ":method"
                                    exact_match: GET
                              route:
                                cluster: player_api_cluster
                                timeout: 30s
                              typed_per_filter_config:
                                envoy.filters.http.ext_authz:
                                  "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
                                  disabled: true

                            - match:
                                path: /api/v1/shops
                                headers:
                                  - name: ":method"
                                    exact_match: GET
                              route:
                                cluster: shop_api_cluster
                                timeout: 30s
                              typed_per_filter_config:
                                envoy.filters.http.ext_authz:
                                  "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
                                  disabled: true

                            - match:
                                safe_regex:
                                  google_re2: {}
                                  regex: "^/api/v1/shops/[0-9]+$"
                                headers:
                                  - name: ":method"
                                    exact_match: GET
                              route:
                                cluster: shop_api_cluster
                                timeout: 30s
                              typed_per_filter_config:
                                envoy.filters.http.ext_authz:
                                  "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
                                  disabled: true

                            - match:
                                safe_regex:
                                  google_re2: {}
                                  regex: "^/api/v1/users/[0-9]+$"
                                headers:
                                  - name: ":method"
                                    exact_match: GET
                              route:
                                cluster: user_api_cluster
                                timeout: 30s
                              typed_per_filter_config:
                                envoy.filters.http.ext_authz:
                                  "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
                                  disabled: true

                            - match:
                                safe_regex:
                                  google_re2: {}
                                  regex: "^/api/v1/users/[0-9]+/posts$"
                                headers:
                                  - name: ":method"
                                    exact_match: GET
                              route:
                                cluster: community_api_cluster
                                timeout: 30s
                              typed_per_filter_config:
                                envoy.filters.http.ext_authz:
                                  "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
                                  disabled: true

                            - match:
                                safe_regex:
                                  google_re2: {}
                                  regex: "^/api/v1/users/[0-9]+/shop$"
                                headers:
                                  - name: ":method"
                                    exact_match: GET
                              route:
                                cluster: shop_api_cluster
                                timeout: 30s
                              typed_per_filter_config:
                                envoy.filters.http.ext_authz:
                                  "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
                                  disabled: true

                            - match:
                                path: /api/v1/search
                                headers:
                                  - name: ":method"
                                    exact_match: GET
                              route:
                                cluster: search_api_cluster
                                timeout: 30s
                              typed_per_filter_config:
                                envoy.filters.http.ext_authz:
                                  "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
                                  disabled: true

                            - match:
                                prefix: /api/v1/recommendations
                                headers:
                                  - name: ":method"
                                    exact_match: GET
                              route:
                                cluster: search_api_cluster
                                timeout: 30s
                              typed_per_filter_config:
                                envoy.filters.http.ext_authz:
                                  "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
                                  disabled: true

                            - match:
                                prefix: /api/v1/posts
                                headers:
                                  - name: ":method"
                                    exact_match: GET
                              route:
                                cluster: community_api_cluster
                                timeout: 30s
                              typed_per_filter_config:
                                envoy.filters.http.ext_authz:
                                  "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
                                  disabled: true

                            - match:
                                prefix: /api/v1/auth
                              route:
                                cluster: user_api_cluster
                                timeout: 30s

                            - match:
                                prefix: /api/v1/admin
                              route:
                                cluster: user_api_cluster
                                timeout: 30s

                            - match:
                                safe_regex:
                                  google_re2: {}
                                  regex: "^/api/v1/users/[0-9]+/favorites/check$"
                              route:
                                cluster: search_api_cluster
                                timeout: 30s

                            - match:
                                safe_regex:
                                  google_re2: {}
                                  regex: "^/api/v1/users/[0-9]+/reviews$"
                                headers:
                                  - name: ":method"
                                    exact_match: GET
                              route:
                                cluster: review_api_cluster
                                timeout: 30s
                              typed_per_filter_config:
                                envoy.filters.http.ext_authz:
                                  "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
                                  disabled: true

                            - match:
                                prefix: /api/v1/users
                              route:
                                cluster: user_api_cluster
                                timeout: 30s

                            - match:
                                prefix: /api/v1/email
                              route:
                                cluster: email_api_cluster
                                timeout: 30s

                            - match:
                                prefix: /api/v1/games
                              route:
                                cluster: game_api_cluster
                                timeout: 30s

                            - match:
                                prefix: /api/v1/players
                              route:
                                cluster: player_api_cluster
                                timeout: 30s

                            - match:
                                prefix: /api/v1/services
                              route:
                                cluster: player_api_cluster
                                timeout: 30s

                            - match:
                                prefix: /api/v1/shops
                              route:
                                cluster: shop_api_cluster
                                timeout: 30s

                            - match:
                                safe_regex:
                                  google_re2: {}
                                  regex: "^/api/v1/orders/[0-9]+/review.*"
                              route:
                                cluster: review_api_cluster
                                timeout: 30s

                            - match:
                                safe_regex:
                                  google_re2: {}
                                  regex: "^/api/v1/orders/[0-9]+/dispute$"
                              route:
                                cluster: dispute_api_cluster
                                timeout: 30s

                            - match:
                                prefix: /api/v1/orders
                              route:
                                cluster: order_api_cluster
                                timeout: 30s

                            - match:
                                prefix: /api/v1/wallet
                              route:
                                cluster: wallet_api_cluster
                                timeout: 30s

                            - match:
                                prefix: /api/v1/posts
                              route:
                                cluster: community_api_cluster
                                timeout: 30s

                            - match:
                                prefix: /api/v1/comments
                              route:
                                cluster: community_api_cluster
                                timeout: 30s

                            - match:
                                path: /ws/chat
                              route:
                                cluster: chat_api_cluster
                                timeout: 0s
                                upgrade_configs:
                                  - upgrade_type: websocket

                            - match:
                                path: /api/v1/upload
                              route:
                                cluster: objectstory_api_cluster
                                timeout: 30s

                            - match:
                                prefix: /api/v1/files
                              route:
                                cluster: objectstory_api_cluster
                                timeout: 30s

                            - match:
                                prefix: /api/v1/reviews
                                headers:
                                  - name: ":method"
                                    exact_match: GET
                              route:
                                cluster: review_api_cluster
                                timeout: 30s
                              typed_per_filter_config:
                                envoy.filters.http.ext_authz:
                                  "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
                                  disabled: true

                            - match:
                                prefix: /api/v1/disputes
                              route:
                                cluster: dispute_api_cluster
                                timeout: 30s

                            - match:
                                prefix: /api/v1/notifications
                              route:
                                cluster: notification_api_cluster
                                timeout: 30s

                            - match:
                                prefix: /api/v1/favorites
                              route:
                                cluster: search_api_cluster
                                timeout: 30s

                            - match:
                                prefix: /
                              route:
                                cluster: frontend_cluster
                                timeout: 30s
                              typed_per_filter_config:
                                envoy.filters.http.ext_authz:
                                  "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
                                  disabled: true

                    access_log:
                      - name: envoy.access_loggers.stdout
                        typed_config:
                          "@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
                          log_format:
                            json_format:
                              start_time: "%START_TIME%"
                              method: "%REQ(:METHOD)%"
                              path: "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%"
                              protocol: "%PROTOCOL%"
                              authority: "%REQ(:AUTHORITY)%"
                              user_agent: "%REQ(USER-AGENT)%"
                              request_id: "%REQ(X-REQUEST-ID)%"
                              response_code: "%RESPONSE_CODE%"
                              response_flags: "%RESPONSE_FLAGS%"
                              bytes_received: "%BYTES_RECEIVED%"
                              bytes_sent: "%BYTES_SENT%"
                              duration_ms: "%DURATION%"
                              upstream_cluster: "%UPSTREAM_CLUSTER%"
                              upstream_host: "%UPSTREAM_HOST%"
                              upstream_service_time_ms: "%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%"
                              route_name: "%ROUTE_NAME%"

                    http_filters:
                      - name: envoy.filters.http.lua
                        typed_config:
                          "@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
                          inline_code: |
                            local TOKEN_HEADER = "xsrf-token"
                            local TOKEN_COOKIE = "__Host-XSRF-TOKEN"
                            local GUARD_COOKIE = "__Host-XSRF-GUARD"

                            local seeded = false

                            local function seed_random()
                              if seeded then
                                return
                              end
                              seeded = true
                              math.randomseed(os.time())
                            end

                            local function split_cookie(header)
                              local out = {}
                              if not header then
                                return out
                              end
                              for pair in string.gmatch(header, "([^;]+)") do
                                local key, value = string.match(pair, "^%s*([^=]+)=?(.*)$")
                                if key ~= nil and value ~= nil then
                                  out[string.lower(key)] = value
                                end
                              end
                              return out
                            end

                            local function is_safe_method(method)
                              return method == "GET" or method == "HEAD" or method == "OPTIONS"
                            end

                            local function build_token(request_id)
                              seed_random()
                              local rnd = tostring(math.random(100000, 999999))
                              local rid = request_id or "rid"
                              return tostring(os.time()) .. "-" .. rid .. "-" .. rnd
                            end

                            function envoy_on_request(request_handle)
                              local headers = request_handle:headers()
                              local method = headers:get(":method")

                              local cookie_header = headers:get("cookie")
                              local cookies = split_cookie(cookie_header)
                              local token_cookie = cookies[string.lower(TOKEN_COOKIE)]
                              local guard_cookie = cookies[string.lower(GUARD_COOKIE)]

                              request_handle:streamInfo():dynamicMetadata():set("csrf", "need_set_token_cookie", token_cookie == nil or token_cookie == "")
                              request_handle:streamInfo():dynamicMetadata():set("csrf", "need_set_guard_cookie", guard_cookie == nil or guard_cookie == "")

                              if token_cookie == nil or token_cookie == "" then
                                token_cookie = build_token(headers:get("x-request-id"))
                                request_handle:streamInfo():dynamicMetadata():set("csrf", "token_value", token_cookie)
                              else
                                request_handle:streamInfo():dynamicMetadata():set("csrf", "token_value", token_cookie)
                              end

                              if guard_cookie == nil or guard_cookie == "" then
                                guard_cookie = build_token(headers:get("x-request-id"))
                                request_handle:streamInfo():dynamicMetadata():set("csrf", "guard_value", guard_cookie)
                              else
                                request_handle:streamInfo():dynamicMetadata():set("csrf", "guard_value", guard_cookie)
                              end

                              if is_safe_method(method) then
                                return
                              end

                              local token_header = headers:get(TOKEN_HEADER)

                              if token_header == nil or token_header == "" then
                                request_handle:respond(
                                  {[":status"] = "403", ["content-type"] = "application/json"},
                                  '{"code":403,"message":"missing XSRF-TOKEN header"}'
                                )
                                return
                              end

                              if token_cookie == nil or token_cookie == "" or guard_cookie == nil or guard_cookie == "" then
                                request_handle:respond(
                                  {[":status"] = "403", ["content-type"] = "application/json"},
                                  '{"code":403,"message":"missing csrf cookies"}'
                                )
                                return
                              end

                              if token_header ~= token_cookie then
                                request_handle:respond(
                                  {[":status"] = "403", ["content-type"] = "application/json"},
                                  '{"code":403,"message":"xsrf token mismatch"}'
                                )
                                return
                              end
                            end

                            function envoy_on_response(response_handle)
                              local metadata = response_handle:streamInfo():dynamicMetadata():get("csrf")
                              if metadata == nil then
                                return
                              end

                              local token_value = metadata["token_value"]
                              local guard_value = metadata["guard_value"]

                              if metadata["need_set_token_cookie"] == true and token_value ~= nil and token_value ~= "" then
                                response_handle:headers():add(
                                  "set-cookie",
                                  TOKEN_COOKIE .. "=" .. token_value .. "; Path=/; Max-Age=7200; SameSite=Strict; Secure"
                                )
                              end

                              if metadata["need_set_guard_cookie"] == true and guard_value ~= nil and guard_value ~= "" then
                                response_handle:headers():add(
                                  "set-cookie",
                                  GUARD_COOKIE .. "=" .. guard_value .. "; Path=/; Max-Age=7200; SameSite=Strict; Secure; HttpOnly"
                                )
                              end
                            end

                      - name: envoy.filters.http.jwt_authn
                        typed_config:
                          "@type": type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.JwtAuthentication
                          providers:
                            juwan_user_jwt:
                              issuer: juwan-user-rpc
                              from_cookies:
                                - JToken
                              local_jwks:
                                inline_string: '{"keys":[{"kty":"oct","k":"TUdVeU1XRTNaRGhqTVRRNVpEZzFNV1ZpT1dVME1HTTNPVEUyTldWa1lUQmxPVEU1WldSa1pEVTFZall6T0dKak9XUmlOek0wTlRjNE5ESXlNamxrWlE","alg":"HS256","use":"sig","kid":"juwan-hs256-1"}]}'
                              forward: false
                              claim_to_headers:
                                - header_name: x-auth-user-id
                                  claim_name: UserId
                                - header_name: x-auth-is-admin
                                  claim_name: IsAdmin
                          rules:
                            - match:
                                path: /healthz
                            - match:
                                path: /ws/chat
                              requires:
                                provider_name: juwan_user_jwt
                            - match:
                                prefix: /api/v1
                                headers:
                                  - name: ":method"
                                    exact_match: OPTIONS
                            - match:
                                path: /api/v1/auth/login
                            - match:
                                path: /api/v1/auth/register
                            - match:
                                path: /api/v1/auth/forgot-password
                            - match:
                                path: /api/v1/auth/reset-password
                            - match:
                                path: /api/v1/auth/forgot-password/send
                            - match:
                                path: /api/v1/email/verification-code/send
                            - match:
                                prefix: /api/v1/games
                                headers:
                                  - name: ":method"
                                    exact_match: GET
                            - match:
                                path: /api/v1/players/me
                                headers:
                                  - name: ":method"
                                    exact_match: GET
                              requires:
                                provider_name: juwan_user_jwt
                            - match:
                                prefix: /api/v1/players
                                headers:
                                  - name: ":method"
                                    exact_match: GET
                            - match:
                                prefix: /api/v1/services
                                headers:
                                  - name: ":method"
                                    exact_match: GET
                            - match:
                                path: /api/v1/shops
                                headers:
                                  - name: ":method"
                                    exact_match: GET
                            - match:
                                safe_regex:
                                  google_re2: {}
                                  regex: "^/api/v1/shops/[0-9]+$"
                                headers:
                                  - name: ":method"
                                    exact_match: GET
                            - match:
                                safe_regex:
                                  google_re2: {}
                                  regex: "^/api/v1/users/[0-9]+$"
                                headers:
                                  - name: ":method"
                                    exact_match: GET
                            - match:
                                safe_regex:
                                  google_re2: {}
                                  regex: "^/api/v1/users/[0-9]+/posts$"
                                headers:
                                  - name: ":method"
                                    exact_match: GET
                              requires:
                                requires_any:
                                  requirements:
                                    - provider_name: juwan_user_jwt
                                    - allow_missing: {}
                            - match:
                                safe_regex:
                                  google_re2: {}
                                  regex: "^/api/v1/users/[0-9]+/shop$"
                                headers:
                                  - name: ":method"
                                    exact_match: GET
                            - match:
                                prefix: /api/v1/posts
                                headers:
                                  - name: ":method"
                                    exact_match: GET
                              requires:
                                requires_any:
                                  requirements:
                                    - provider_name: juwan_user_jwt
                                    - allow_missing: {}
                            - match:
                                prefix: /api/v1/reviews
                                headers:
                                  - name: ":method"
                                    exact_match: GET
                            - match:
                                safe_regex:
                                  google_re2: {}
                                  regex: "^/api/v1/users/[0-9]+/reviews$"
                                headers:
                                  - name: ":method"
                                    exact_match: GET
                            - match:
                                path: /api/v1/search
                                headers:
                                  - name: ":method"
                                    exact_match: GET
                            - match:
                                path: /api/v1/recommendations/home
                                headers:
                                  - name: ":method"
                                    exact_match: GET
                            - match:
                                prefix: /api/v1
                              requires:
                                provider_name: juwan_user_jwt

                      - name: envoy.filters.http.ext_authz
                        typed_config:
                          "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz
                          transport_api_version: V3
                          failure_mode_allow: false
                          with_request_body:
                            max_request_bytes: 8192
                            allow_partial_message: true
                          grpc_service:
                            envoy_grpc:
                              cluster_name: authz_adapter_cluster
                            timeout: 0.5s

                      - name: envoy.filters.http.ratelimit
                        typed_config:
                          "@type": type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit
                          domain: api
                          failure_mode_deny: false
                          rate_limited_as_resource_exhausted: true
                          enable_x_ratelimit_headers: DRAFT_VERSION_03
                          rate_limit_service:
                            transport_api_version: V3
                            grpc_service:
                              envoy_grpc:
                                cluster_name: ratelimit_cluster
                              timeout: 0.2s

                      - name: envoy.filters.http.router
                        typed_config:
                          "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router

      clusters:
        - name: user_api_cluster
          connect_timeout: 2s
          type: STRICT_DNS
          lb_policy: ROUND_ROBIN
          load_assignment:
            cluster_name: user_api_cluster
            endpoints:
              - lb_endpoints:
                  - endpoint:
                      address:
                        socket_address:
                          address: user-api-svc.juwan
                          port_value: 8888

        - name: email_api_cluster
          connect_timeout: 2s
          type: STRICT_DNS
          lb_policy: ROUND_ROBIN
          load_assignment:
            cluster_name: email_api_cluster
            endpoints:
              - lb_endpoints:
                  - endpoint:
                      address:
                        socket_address:
                          address: email-api-svc.juwan
                          port_value: 8888

        - name: player_api_cluster
          connect_timeout: 2s
          type: STRICT_DNS
          lb_policy: ROUND_ROBIN
          load_assignment:
            cluster_name: player_api_cluster
            endpoints:
              - lb_endpoints:
                  - endpoint:
                      address:
                        socket_address:
                          address: player-api-svc.juwan
                          port_value: 8888

        - name: game_api_cluster
          connect_timeout: 2s
          type: STRICT_DNS
          lb_policy: ROUND_ROBIN
          load_assignment:
            cluster_name: game_api_cluster
            endpoints:
              - lb_endpoints:
                  - endpoint:
                      address:
                        socket_address:
                          address: game-api-svc.juwan
                          port_value: 8888

        - name: shop_api_cluster
          connect_timeout: 2s
          type: STRICT_DNS
          lb_policy: ROUND_ROBIN
          load_assignment:
            cluster_name: shop_api_cluster
            endpoints:
              - lb_endpoints:
                  - endpoint:
                      address:
                        socket_address:
                          address: shop-api-svc.juwan
                          port_value: 8888

        - name: order_api_cluster
          connect_timeout: 2s
          type: STRICT_DNS
          lb_policy: ROUND_ROBIN
          load_assignment:
            cluster_name: order_api_cluster
            endpoints:
              - lb_endpoints:
                  - endpoint:
                      address:
                        socket_address:
                          address: order-api-svc.juwan
                          port_value: 8888

        - name: wallet_api_cluster
          connect_timeout: 2s
          type: STRICT_DNS
          lb_policy: ROUND_ROBIN
          load_assignment:
            cluster_name: wallet_api_cluster
            endpoints:
              - lb_endpoints:
                  - endpoint:
                      address:
                        socket_address:
                          address: wallet-api-svc.juwan
                          port_value: 8888

        - name: community_api_cluster
          connect_timeout: 2s
          type: STRICT_DNS
          lb_policy: ROUND_ROBIN
          load_assignment:
            cluster_name: community_api_cluster
            endpoints:
              - lb_endpoints:
                  - endpoint:
                      address:
                        socket_address:
                          address: community-api-svc.juwan
                          port_value: 8888

        - name: objectstory_api_cluster
          connect_timeout: 2s
          type: STRICT_DNS
          lb_policy: ROUND_ROBIN
          load_assignment:
            cluster_name: objectstory_api_cluster
            endpoints:
              - lb_endpoints:
                  - endpoint:
                      address:
                        socket_address:
                          address: objectstory-api-svc.juwan
                          port_value: 8888

        - name: chat_api_cluster
          connect_timeout: 2s
          type: STRICT_DNS
          lb_policy: ROUND_ROBIN
          load_assignment:
            cluster_name: chat_api_cluster
            endpoints:
              - lb_endpoints:
                  - endpoint:
                      address:
                        socket_address:
                          address: chat-api-svc.juwan
                          port_value: 8888

        - name: review_api_cluster
          connect_timeout: 2s
          type: STRICT_DNS
          lb_policy: ROUND_ROBIN
          load_assignment:
            cluster_name: review_api_cluster
            endpoints:
              - lb_endpoints:
                  - endpoint:
                      address:
                        socket_address:
                          address: review-api-svc.juwan
                          port_value: 8888

        - name: dispute_api_cluster
          connect_timeout: 2s
          type: STRICT_DNS
          lb_policy: ROUND_ROBIN
          load_assignment:
            cluster_name: dispute_api_cluster
            endpoints:
              - lb_endpoints:
                  - endpoint:
                      address:
                        socket_address:
                          address: dispute-api-svc.juwan
                          port_value: 8888

        - name: notification_api_cluster
          connect_timeout: 2s
          type: STRICT_DNS
          lb_policy: ROUND_ROBIN
          load_assignment:
            cluster_name: notification_api_cluster
            endpoints:
              - lb_endpoints:
                  - endpoint:
                      address:
                        socket_address:
                          address: notification-api-svc.juwan
                          port_value: 8888

        - name: search_api_cluster
          connect_timeout: 2s
          type: STRICT_DNS
          lb_policy: ROUND_ROBIN
          load_assignment:
            cluster_name: search_api_cluster
            endpoints:
              - lb_endpoints:
                  - endpoint:
                      address:
                        socket_address:
                          address: search-api-svc.juwan
                          port_value: 8888

        - name: authz_adapter_cluster
          connect_timeout: 0.5s
          type: STRICT_DNS
          lb_policy: ROUND_ROBIN
          http2_protocol_options: {}
          load_assignment:
            cluster_name: authz_adapter_cluster
            endpoints:
              - lb_endpoints:
                  - endpoint:
                      address:
                        socket_address:
                          address: authz-adapter-svc.juwan
                          port_value: 9002

        - name: ratelimit_cluster
          connect_timeout: 0.25s
          type: STRICT_DNS
          lb_policy: ROUND_ROBIN
          http2_protocol_options: {}
          load_assignment:
            cluster_name: ratelimit_cluster
            endpoints:
              - lb_endpoints:
                  - endpoint:
                      address:
                        socket_address:
                          address: ratelimit-svc.juwan
                          port_value: 8081

        - name: frontend_cluster
          connect_timeout: 2s
          type: STRICT_DNS
          lb_policy: ROUND_ROBIN
          load_assignment:
            cluster_name: frontend_cluster
            endpoints:
              - lb_endpoints:
                  - endpoint:
                      address:
                        socket_address:
                          address: frontend-svc.juwan
                          port_value: 3000

    admin:
      access_log_path: /tmp/admin.log
      address:
        socket_address:
          address: 0.0.0.0
          port_value: 9901

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: envoy-gateway
  namespace: juwan
  labels:
    app: envoy-gateway
spec:
  replicas: 1
  selector:
    matchLabels:
      app: envoy-gateway
  template:
    metadata:
      labels:
        app: envoy-gateway
    spec:
      serviceAccountName: envoy-gateway
      containers:
        - name: envoy
          image: envoyproxy/envoy:v1.38.0
          command:
            - /usr/local/bin/envoy
            - -c
            - /etc/envoy/envoy.yaml
            - --log-level
            - info
            - --disable-hot-restart
          ports:
            - containerPort: 8080
              name: http
            - containerPort: 9901
              name: admin
          volumeMounts:
            - name: config
              mountPath: /etc/envoy
          readinessProbe:
            httpGet:
              path: /healthz
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 10
          resources:
            requests:
              cpu: 30m
              memory: 20Mi
            limits:
              memory: 120Mi
      volumes:
        - name: config
          configMap:
            name: envoy-config

---
apiVersion: v1
kind: Service
metadata:
  name: envoy-gateway-svc
  namespace: juwan
spec:
  type: NodePort
  ports:
    - name: http
      port: 8080
      targetPort: 8080
      nodePort: 30080
  selector:
    app: envoy-gateway

---
apiVersion: v1
kind: Service
metadata:
  name: envoy-admin-svc
  namespace: juwan
spec:
  ports:
    - name: admin
      port: 9901
      targetPort: 9901
  selector:
    app: envoy-gateway
