envoyproxy / gateway

Manages Envoy Proxy as a Standalone or Kubernetes-based Application Gateway
https://gateway.envoyproxy.io
Apache License 2.0
1.46k stars 305 forks source link

Support Envoy LocalReplyConfig Settings #1400

Open qicz opened 1 year ago

qicz commented 1 year ago

xref: https://www.envoyproxy.io/docs/envoy/v1.25.0/configuration/http/http_conn_man/local_reply.html?highlight=local%20reply

apiVersion: config.gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
  name: with-local-reply-config
spec:
  localReplyConfig:
    mappers:
    - filter:
        status_code_filter:
          comparison:
            op: EQ
            value:
              default_value: 400
              runtime_key: key_b
      status_code: 401
      body_format_override:
        text_format: "<h1>%LOCAL_REPLY_BODY% %REQ(:path)%</h1>"
        content_type: "text/html; charset=UTF-8"
    - filter:
        status_code_filter:
          comparison:
            op: EQ
            value:
              default_value: 500
              runtime_key: key_b
      status_code: 501
    bodyFormat:
      text_format: "%LOCAL_REPLY_BODY% %RESPONSE_CODE%"

using the go-control-panel API, so some file naming styles followed

API definition

// EnvoyProxySpec defines the desired state of EnvoyProxy.
type EnvoyProxySpec struct {
    // Provider defines the desired resource provider and provider-specific configuration.
    // If unspecified, the "Kubernetes" resource provider is used with default configuration
    // parameters.
    //
    // +optional
    Provider *EnvoyProxyProvider `json:"provider,omitempty"`

    // Logging defines logging parameters for managed proxies. If unspecified,
    // default settings apply. This type is not implemented until
    // https://github.com/envoyproxy/gateway/issues/280 is fixed.
    //
    // +kubebuilder:default={level: {system: info}}
    Logging ProxyLogging `json:"logging,omitempty"`

    // Bootstrap defines the Envoy Bootstrap as a YAML string.
    // Visit https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/bootstrap/v3/bootstrap.proto#envoy-v3-api-msg-config-bootstrap-v3-bootstrap
    // to learn more about the syntax.
    // If set, this is the Bootstrap configuration used for the managed Envoy Proxy fleet instead of the default Bootstrap configuration
    // set by Envoy Gateway.
    // Some fields within the Bootstrap that are required to communicate with the xDS Server (Envoy Gateway) and receive xDS resources
    // from it are not configurable and will result in the `EnvoyProxy` resource being rejected.
    // Backward compatibility across minor versions is not guaranteed.
    // We strongly recommend using `egctl x translate` to generate a `EnvoyProxy` resource with the `Bootstrap` field set to the default
    // Bootstrap configuration used. You can edit this configuration, and rerun `egctl x translate` to ensure there are no validation errors.
    //
    // +optional
    Bootstrap *string `json:"bootstrap,omitempty"`

    // The configuration to customize local reply returned by Envoy. It can customize status code,
    // body text and response content type. If not specified, status code and text body are hard
    // coded in Envoy, the response content type is plain text.
    //
    // +optional
    LocalReplyConfig *LocalReplyConfig `json:"localReplyConfig,omitempty"`
}

type LocalReplyConfig struct {

    // Configuration of list of mappers which allows to filter and change local response.
    // The mappers will be checked by the specified order until one is matched.
    Mappers []*hcmv3.ResponseMapper `json:"mappers,omitempty"`
    // The configuration to form response body from the :ref:`command operators <config_access_log_command_operators>`
    // and to specify response content type as one of: plain/text or application/json.
    //
    // Example one: "plain/text" ``body_format``.
    //
    // .. validated-code-block:: yaml
    //   :type-name: envoy.config.core.v3.SubstitutionFormatString
    //
    //   text_format: "%LOCAL_REPLY_BODY%:%RESPONSE_CODE%:path=%REQ(:path)%\n"
    //
    // The following response body in "plain/text" format will be generated for a request with
    // local reply body of "upstream connection error", response_code=503 and path=/foo.
    //
    // .. code-block:: text
    //
    //   upstream connect error:503:path=/foo
    //
    // Example two: "application/json" ``body_format``.
    //
    // .. validated-code-block:: yaml
    //   :type-name: envoy.config.core.v3.SubstitutionFormatString
    //
    //   json_format:
    //     status: "%RESPONSE_CODE%"
    //     message: "%LOCAL_REPLY_BODY%"
    //     path: "%REQ(:path)%"
    //
    // The following response body in "application/json" format would be generated for a request with
    // local reply body of "upstream connection error", response_code=503 and path=/foo.
    //
    // .. code-block:: json
    //
    //  {
    //    "status": 503,
    //    "message": "upstream connection error",
    //    "path": "/foo"
    //  }
    //
    BodyFormat *corev3.SubstitutionFormatString `json:"bodyFormat,omitempty"`
}
zirain commented 1 year ago

what's the use case? please make an agreement before starting to work

qicz commented 1 year ago

what's the use case? please make an agreement before starting to work

custom the exception error page or message, like 503, 500, 404, or others and custom exception error response data structure, more ref the envoy doc https://www.envoyproxy.io/docs/envoy/v1.25.0/configuration/http/http_conn_man/local_reply.html?highlight=local%20reply

zirain commented 1 year ago

like this? so I think is a kind of route or per listener?

qicz commented 1 year ago

like this? so I think is a kind of route or per listener?

the locaReplyConfig is a setting for HttpConnectionManager. and it is different from DirectResponse

arkodg commented 1 year ago

hoping #24 can solve your issue I will also raise a issue upstream for a ResponseBodyModifier filter

arkodg commented 1 year ago

raised https://github.com/kubernetes-sigs/gateway-api/issues/1998

qicz commented 1 year ago

Imo, the ResponseBodyModifier is a filter for route, but the localReplyConfig is the global exception config

zirain commented 1 year ago

I recall there's an upstream issue about global filter, @arkodg do you recall anything?

github-actions[bot] commented 1 year ago

This issue has been automatically marked as stale because it has not had activity in the last 30 days.

github-actions[bot] commented 5 months ago

This issue has been automatically marked as stale because it has not had activity in the last 30 days.

arkodg commented 3 months ago

@davidalger brought this up in the community meeting today, everyone in the call was a big +1 on the feature, requires an API design, though, and a little more brainstorming is needed whether we can combine a few sub features into one or not -

arkodg commented 3 months ago

temporarily assigning this to you @davidalger, tia !

github-actions[bot] commented 2 months ago

This issue has been automatically marked as stale because it has not had activity in the last 30 days.

github-actions[bot] commented 3 weeks ago

This issue has been automatically marked as stale because it has not had activity in the last 30 days.