apiVersion: v1
kind: ConfigMap
metadata:
  name: envoy-config
  namespace: juwan
data:
  envoy.yaml: |
    static_resources:
      listeners:
        - name: ingress_http
          address:
            socket_address:
              address: 0.0.0.0
              port_value: 8080
          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
                    internal_address_config:
                      cidr_ranges:
                        - address_prefix: 10.0.0.0
                          prefix_len: 8
                        - address_prefix: 172.16.0.0
                          prefix_len: 12
                        - address_prefix: 192.168.0.0
                          prefix_len: 16
                        - address_prefix: 127.0.0.0
                          prefix_len: 8
                    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
                              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
                              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
                              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/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
                              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/users
                              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/email/verification-code/send
                              route:
                                cluster: email_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/email
                              route:
                                cluster: email_api_cluster
                                timeout: 30s

                            - match:
                                prefix: /api/v1/auth
                              route:
                                cluster: user_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/shop
                           #   route:
                           #     cluster: player_api_cluster
                           #     timeout: 30s
                            # - match:
                            #     prefix: /api/v1/orders
                            #   route:
                            #     cluster: order_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:
                            #     prefix: /api/v1/wallet
                            #   route:
                            #     cluster: wallet_api_cluster
                            #     timeout: 30s
                            # - match:
                            #     prefix: /api/v1/disputes
                            #   route:
                            #     cluster: dispute_api_cluster
                            #     timeout: 30s
                            # - match:
                            #     safe_regex:
                            #       google_re2: {}
                            #       regex: "^/api/v1/orders/[^/]+/dispute$"
                            #   route:
                            #     cluster: dispute_api_cluster
                            #     timeout: 30s
                            # - match:
                            #     prefix: /api/v1/reviews
                            #   route:
                            #     cluster: review_api_cluster
                            #     timeout: 30s
                            # - match:
                            #     safe_regex:
                            #       google_re2: {}
                            #       regex: "^/api/v1/orders/[^/]+/review(s)?$"
                            #   route:
                            #     cluster: review_api_cluster
                            #     timeout: 30s
                            # - match:
                            #     prefix: /api/v1/posts
                            #   route:
                            #     cluster: community_api_cluster
                            #     timeout: 30s
                            # - match:
                            #     safe_regex:
                            #       google_re2: {}
                            #       regex: "^/api/v1/comments/[^/]+/like$"
                            #   route:
                            #     cluster: community_api_cluster
                            #     timeout: 30s
                            # - match:
                            #     path: /api/v1/search
                            #   route:
                            #     cluster: search_api_cluster
                            #     timeout: 30s
                            # - match:
                            #     path: /api/v1/recommendations/home
                            #   route:
                            #     cluster: search_api_cluster
                            #     timeout: 30s
                            # - match:
                            #     prefix: /api/v1/notifications
                            #   route:
                            #     cluster: notification_api_cluster
                            #     timeout: 30s
                            # - match:
                            #     prefix: /api/v1/chat
                            #   route:
                            #     cluster: chat_api_cluster
                            #     timeout: 30s
                            # - match:
                            #     prefix: /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
                              route:
                                cluster: user_api_cluster
                                timeout: 30s

                            - match:
                                prefix: /api/email
                              route:
                                cluster: email_api_cluster
                                timeout: 30s
                            
                            - match:
                                prefix: /
                              direct_response:
                                status: 404
                                body:
                                  inline_string: "gateway route not found"
                    
                    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:
                                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:
                                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/search"
                                headers:
                                  - name: ":method"
                                    exact_match: "GET"
                            - match:
                                path: "/api/v1/recommendations/home"
                                headers:
                                  - name: ":method"
                                    exact_match: "GET"
                            - match:
                                prefix: "/api/v1/posts"
                                headers:
                                  - name: ":method"
                                    exact_match: "GET"
                            - match:
                                prefix: "/api/v1/reviews"
                                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/[^/]+$"
                                headers:
                                  - name: ":method"
                                    exact_match: "GET"
                            - match:
                                safe_regex:
                                  google_re2: {}
                                  regex: "^/api/v1/shops/[^/]+/players$"
                                headers:
                                  - name: ":method"
                                    exact_match: "GET"
                            - match:
                                safe_regex:
                                  google_re2: {}
                                  regex: "^/api/v1/users/[^/]+$"
                                headers:
                                  - name: ":method"
                                    exact_match: "GET"
                            - match:
                                safe_regex:
                                  google_re2: {}
                                  regex: "^/api/v1/users/[^/]+/posts$"
                                headers:
                                  - name: ":method"
                                    exact_match: "GET"
                            - match:
                                safe_regex:
                                  google_re2: {}
                                  regex: "^/api/v1/users/[^/]+/reviews$"
                                headers:
                                  - name: ":method"
                                    exact_match: "GET"
                            - match:
                                safe_regex:
                                  google_re2: {}
                                  regex: "^/api/v1/users/[^/]+/shop$"
                                headers:
                                  - name: ":method"
                                    exact_match: "GET"

                            - match:
                                prefix: "/api/v1"
                              requires:
                                provider_name: juwan_user_jwt

                            - match:
                                prefix: "/api/users"
                              requires:
                                provider_name: juwan_user_jwt
                            - match:
                                prefix: "/api/email"
                              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.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.svc.cluster.local
                          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.svc.cluster.local
                          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.svc.cluster.local
                          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.svc.cluster.local
                         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.svc.cluster.local
                          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.svc.cluster.local
                         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.svc.cluster.local
                          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.svc.cluster.local
                         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.svc.cluster.local
        #                   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.svc.cluster.local
        #                   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.svc.cluster.local
        #                   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.svc.cluster.local
        #                   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.svc.cluster.local
        #                   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.svc.cluster.local
        #                   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.svc.cluster.local
        #                   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.svc.cluster.local
        #                   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.svc.cluster.local
        #                   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.svc.cluster.local
                          port_value: 9002

    admin:
      access_log_path: /tmp/admin_access.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: 2
  revisionHistoryLimit: 5
  selector:
    matchLabels:
      app: envoy-gateway
  template:
    metadata:
      labels:
        app: envoy-gateway
    spec:
      serviceAccountName: envoy-gateway
      containers:
        - name: envoy
          image: envoyproxy/envoy:v1.31-latest
          imagePullPolicy: IfNotPresent
          command: ["/usr/local/bin/envoy"]
          args:
            - "-c"
            - "/etc/envoy/envoy.yaml"
            - "--log-level"
            - "info"
          ports:
            - containerPort: 8080
              name: http
            - containerPort: 9901
              name: admin
          livenessProbe:
            httpGet:
              path: /healthz
              port: 8080
            initialDelaySeconds: 10
            periodSeconds: 15
          readinessProbe:
            httpGet:
              path: /healthz
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 10
          volumeMounts:
            - name: envoy-config
              mountPath: /etc/envoy
      volumes:
        - name: envoy-config
          configMap:
            name: envoy-config

---
apiVersion: v1
kind: Service
metadata:
  name: envoy-gateway
  namespace: juwan
spec:
  selector:
    app: envoy-gateway
  ports:
    - name: http
      port: 80
      targetPort: 8080
    - name: admin
      port: 9901
      targetPort: 9901
  type: ClusterIP
