From 8d89892ccea38c769ebc0405758adf13b9ee80e5 Mon Sep 17 00:00:00 2001 From: htuch Date: Mon, 8 Jun 2020 20:35:27 -0400 Subject: [PATCH] api: populate secure edge defaults manifest. (#11364) Adding API annotations and manifest entries to match https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/edge#best-practices-edge. Risk level: Low (API/docs only change) Testing: Docs build and inspection. Fixes #11085 Signed-off-by: Harvey Tuch --- api/envoy/config/cluster/v3/cluster.proto | 7 ++- .../config/cluster/v4alpha/cluster.proto | 7 ++- .../v3/http_connection_manager.proto | 16 ++++-- .../v4alpha/http_connection_manager.proto | 16 ++++-- docs/BUILD | 2 +- docs/edge_defaults_manifest.yaml | 21 -------- docs/protodoc_manifest.yaml | 51 +++++++++++++++++++ .../envoy/config/cluster/v3/cluster.proto | 7 ++- .../config/cluster/v4alpha/cluster.proto | 7 ++- .../v3/http_connection_manager.proto | 16 ++++-- .../v4alpha/http_connection_manager.proto | 16 ++++-- tools/protodoc/BUILD | 11 +++- tools/protodoc/manifest.proto | 29 +++++++++++ tools/protodoc/protodoc.py | 39 +++++++++----- 14 files changed, 180 insertions(+), 65 deletions(-) delete mode 100644 docs/edge_defaults_manifest.yaml create mode 100644 docs/protodoc_manifest.yaml create mode 100644 tools/protodoc/manifest.proto diff --git a/api/envoy/config/cluster/v3/cluster.proto b/api/envoy/config/cluster/v3/cluster.proto index be7710815b70..7eb53d84c4f8 100644 --- a/api/envoy/config/cluster/v3/cluster.proto +++ b/api/envoy/config/cluster/v3/cluster.proto @@ -19,6 +19,7 @@ import "google/protobuf/struct.proto"; import "google/protobuf/wrappers.proto"; import "envoy/annotations/deprecation.proto"; +import "udpa/annotations/security.proto"; import "udpa/annotations/status.proto"; import "udpa/annotations/versioning.proto"; import "validate/validate.proto"; @@ -584,7 +585,8 @@ message Cluster { // Soft limit on size of the cluster’s connections read and write buffers. If // unspecified, an implementation defined default is applied (1MiB). - google.protobuf.UInt32Value per_connection_buffer_limit_bytes = 5; + google.protobuf.UInt32Value per_connection_buffer_limit_bytes = 5 + [(udpa.annotations.security).configure_for_untrusted_upstream = true]; // The :ref:`load balancer type ` to use // when picking a host in the cluster. @@ -635,7 +637,8 @@ message Cluster { // supports prior knowledge for upstream connections. Even if TLS is used // with ALPN, `http2_protocol_options` must be specified. As an aside this allows HTTP/2 // connections to happen over plain text. - core.v3.Http2ProtocolOptions http2_protocol_options = 14; + core.v3.Http2ProtocolOptions http2_protocol_options = 14 + [(udpa.annotations.security).configure_for_untrusted_upstream = true]; // The extension_protocol_options field is used to provide extension-specific protocol options // for upstream connections. The key should match the extension filter name, such as diff --git a/api/envoy/config/cluster/v4alpha/cluster.proto b/api/envoy/config/cluster/v4alpha/cluster.proto index 2b044b2c6437..eab2f2d80fcb 100644 --- a/api/envoy/config/cluster/v4alpha/cluster.proto +++ b/api/envoy/config/cluster/v4alpha/cluster.proto @@ -19,6 +19,7 @@ import "google/protobuf/struct.proto"; import "google/protobuf/wrappers.proto"; import "envoy/annotations/deprecation.proto"; +import "udpa/annotations/security.proto"; import "udpa/annotations/status.proto"; import "udpa/annotations/versioning.proto"; import "validate/validate.proto"; @@ -585,7 +586,8 @@ message Cluster { // Soft limit on size of the cluster’s connections read and write buffers. If // unspecified, an implementation defined default is applied (1MiB). - google.protobuf.UInt32Value per_connection_buffer_limit_bytes = 5; + google.protobuf.UInt32Value per_connection_buffer_limit_bytes = 5 + [(udpa.annotations.security).configure_for_untrusted_upstream = true]; // The :ref:`load balancer type ` to use // when picking a host in the cluster. @@ -636,7 +638,8 @@ message Cluster { // supports prior knowledge for upstream connections. Even if TLS is used // with ALPN, `http2_protocol_options` must be specified. As an aside this allows HTTP/2 // connections to happen over plain text. - core.v4alpha.Http2ProtocolOptions http2_protocol_options = 14; + core.v4alpha.Http2ProtocolOptions http2_protocol_options = 14 + [(udpa.annotations.security).configure_for_untrusted_upstream = true]; // The extension_protocol_options field is used to provide extension-specific protocol options // for upstream connections. The key should match the extension filter name, such as diff --git a/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index b46e63076d7a..355eaba01e93 100644 --- a/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -19,6 +19,7 @@ import "google/protobuf/struct.proto"; import "google/protobuf/wrappers.proto"; import "envoy/annotations/deprecation.proto"; +import "udpa/annotations/security.proto"; import "udpa/annotations/status.proto"; import "udpa/annotations/versioning.proto"; import "validate/validate.proto"; @@ -281,13 +282,15 @@ message HttpConnectionManager { // Additional settings for HTTP requests handled by the connection manager. These will be // applicable to both HTTP1 and HTTP2 requests. - config.core.v3.HttpProtocolOptions common_http_protocol_options = 35; + config.core.v3.HttpProtocolOptions common_http_protocol_options = 35 + [(udpa.annotations.security).configure_for_untrusted_downstream = true]; // Additional HTTP/1 settings that are passed to the HTTP/1 codec. config.core.v3.Http1ProtocolOptions http_protocol_options = 8; // Additional HTTP/2 settings that are passed directly to the HTTP/2 codec. - config.core.v3.Http2ProtocolOptions http2_protocol_options = 9; + config.core.v3.Http2ProtocolOptions http2_protocol_options = 9 + [(udpa.annotations.security).configure_for_untrusted_downstream = true]; // An optional override that the connection manager will write to the server // header in responses. If not set, the default is *envoy*. @@ -332,13 +335,15 @@ message HttpConnectionManager { // // A value of 0 will completely disable the connection manager stream idle // timeout, although per-route idle timeout overrides will continue to apply. - google.protobuf.Duration stream_idle_timeout = 24; + google.protobuf.Duration stream_idle_timeout = 24 + [(udpa.annotations.security).configure_for_untrusted_downstream = true]; // The amount of time that Envoy will wait for the entire request to be received. // The timer is activated when the request is initiated, and is disarmed when the last byte of the // request is sent upstream (i.e. all decoding filters have processed the request), OR when the // response is initiated. If not specified or set to 0, this timeout is disabled. - google.protobuf.Duration request_timeout = 28; + google.protobuf.Duration request_timeout = 28 + [(udpa.annotations.security).configure_for_untrusted_downstream = true]; // The time that Envoy will wait between sending an HTTP/2 “shutdown // notification” (GOAWAY frame with max stream ID) and a final GOAWAY frame. @@ -394,7 +399,8 @@ message HttpConnectionManager { // :ref:`config_http_conn_man_headers_x-forwarded-for`, // :ref:`config_http_conn_man_headers_x-envoy-internal`, and // :ref:`config_http_conn_man_headers_x-envoy-external-address` for more information. - google.protobuf.BoolValue use_remote_address = 14; + google.protobuf.BoolValue use_remote_address = 14 + [(udpa.annotations.security).configure_for_untrusted_downstream = true]; // The number of additional ingress proxy hops from the right side of the // :ref:`config_http_conn_man_headers_x-forwarded-for` HTTP header to trust when diff --git a/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto b/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto index 482bb5ed95e9..f5e6619dee33 100644 --- a/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto +++ b/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto @@ -19,6 +19,7 @@ import "google/protobuf/struct.proto"; import "google/protobuf/wrappers.proto"; import "envoy/annotations/deprecation.proto"; +import "udpa/annotations/security.proto"; import "udpa/annotations/status.proto"; import "udpa/annotations/versioning.proto"; import "validate/validate.proto"; @@ -281,13 +282,15 @@ message HttpConnectionManager { // Additional settings for HTTP requests handled by the connection manager. These will be // applicable to both HTTP1 and HTTP2 requests. - config.core.v4alpha.HttpProtocolOptions common_http_protocol_options = 35; + config.core.v4alpha.HttpProtocolOptions common_http_protocol_options = 35 + [(udpa.annotations.security).configure_for_untrusted_downstream = true]; // Additional HTTP/1 settings that are passed to the HTTP/1 codec. config.core.v4alpha.Http1ProtocolOptions http_protocol_options = 8; // Additional HTTP/2 settings that are passed directly to the HTTP/2 codec. - config.core.v4alpha.Http2ProtocolOptions http2_protocol_options = 9; + config.core.v4alpha.Http2ProtocolOptions http2_protocol_options = 9 + [(udpa.annotations.security).configure_for_untrusted_downstream = true]; // An optional override that the connection manager will write to the server // header in responses. If not set, the default is *envoy*. @@ -332,13 +335,15 @@ message HttpConnectionManager { // // A value of 0 will completely disable the connection manager stream idle // timeout, although per-route idle timeout overrides will continue to apply. - google.protobuf.Duration stream_idle_timeout = 24; + google.protobuf.Duration stream_idle_timeout = 24 + [(udpa.annotations.security).configure_for_untrusted_downstream = true]; // The amount of time that Envoy will wait for the entire request to be received. // The timer is activated when the request is initiated, and is disarmed when the last byte of the // request is sent upstream (i.e. all decoding filters have processed the request), OR when the // response is initiated. If not specified or set to 0, this timeout is disabled. - google.protobuf.Duration request_timeout = 28; + google.protobuf.Duration request_timeout = 28 + [(udpa.annotations.security).configure_for_untrusted_downstream = true]; // The time that Envoy will wait between sending an HTTP/2 “shutdown // notification” (GOAWAY frame with max stream ID) and a final GOAWAY frame. @@ -394,7 +399,8 @@ message HttpConnectionManager { // :ref:`config_http_conn_man_headers_x-forwarded-for`, // :ref:`config_http_conn_man_headers_x-envoy-internal`, and // :ref:`config_http_conn_man_headers_x-envoy-external-address` for more information. - google.protobuf.BoolValue use_remote_address = 14; + google.protobuf.BoolValue use_remote_address = 14 + [(udpa.annotations.security).configure_for_untrusted_downstream = true]; // The number of additional ingress proxy hops from the right side of the // :ref:`config_http_conn_man_headers_x-forwarded-for` HTTP header to trust when diff --git a/docs/BUILD b/docs/BUILD index d190c0a59a0a..ead7bddb9a7f 100644 --- a/docs/BUILD +++ b/docs/BUILD @@ -1,3 +1,3 @@ licenses(["notice"]) # Apache 2 -exports_files(["edge_defaults_manifest.yaml"]) +exports_files(["protodoc_manifest.yaml"]) diff --git a/docs/edge_defaults_manifest.yaml b/docs/edge_defaults_manifest.yaml deleted file mode 100644 index b5072c26a32b..000000000000 --- a/docs/edge_defaults_manifest.yaml +++ /dev/null @@ -1,21 +0,0 @@ -envoy.config.bootstrap.v3.Bootstrap.overload_manager: - refresh_interval: 0.25s - resource_monitors: - - name: "envoy.resource_monitors.fixed_heap" - typed_config: - "@type": type.googleapis.com/envoy.config.resource_monitor.fixed_heap.v2alpha.FixedHeapConfig - # TODO: Tune for your system. - max_heap_size_bytes: 2147483648 # 2 GiB - actions: - - name: "envoy.overload_actions.shrink_heap" - triggers: - - name: "envoy.resource_monitors.fixed_heap" - threshold: - value: 0.95 - - name: "envoy.overload_actions.stop_accepting_requests" - triggers: - - name: "envoy.resource_monitors.fixed_heap" - threshold: - value: 0.98 - -envoy.config.listener.v3.Listener.per_connection_buffer_limit_bytes: 32768 # 32 KiB diff --git a/docs/protodoc_manifest.yaml b/docs/protodoc_manifest.yaml new file mode 100644 index 000000000000..2e2afff3264d --- /dev/null +++ b/docs/protodoc_manifest.yaml @@ -0,0 +1,51 @@ +fields: + envoy.config.bootstrap.v3.Bootstrap.overload_manager: + edge_config: + example: + refresh_interval: 0.25s + resource_monitors: + - name: "envoy.resource_monitors.fixed_heap" + typed_config: + "@type": type.googleapis.com/envoy.config.resource_monitor.fixed_heap.v2alpha.FixedHeapConfig + max_heap_size_bytes: 1073741824 + actions: + - name: "envoy.overload_actions.shrink_heap" + triggers: + - name: "envoy.resource_monitors.fixed_heap" + threshold: + value: 0.90 + - name: "envoy.overload_actions.stop_accepting_requests" + triggers: + - name: "envoy.resource_monitors.fixed_heap" + threshold: + value: 0.95 + envoy.config.cluster.v3.Cluster.per_connection_buffer_limit_bytes: + edge_config: { example: 32768 } + envoy.config.cluster.v3.Cluster.http2_protocol_options: + edge_config: + example: + initial_stream_window_size: 65536 # 64 KiB + initial_connection_window_size: 1048576 # 1 MiB + envoy.config.listener.v3.Listener.per_connection_buffer_limit_bytes: + edge_config: { example: 32768 } + envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.common_http_protocol_options: + edge_config: + example: + idle_timeout: 900s # 15 mins + headers_with_underscores_action: REJECT_REQUEST + envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.http2_protocol_options: + edge_config: + example: + max_concurrent_streams: 100 + initial_stream_window_size: 65536 # 64 KiB + initial_connection_window_size: 1048576 # 1 MiB + envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.stream_idle_timeout: + edge_config: + example: 300s # 5 mins + envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.request_timeout: + edge_config: + note: > + This timeout is not compatible with streaming requests. + example: 300s # 5 mins + envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.use_remote_address: + edge_config: { example: true } diff --git a/generated_api_shadow/envoy/config/cluster/v3/cluster.proto b/generated_api_shadow/envoy/config/cluster/v3/cluster.proto index f512cbcc9d22..8140007f68af 100644 --- a/generated_api_shadow/envoy/config/cluster/v3/cluster.proto +++ b/generated_api_shadow/envoy/config/cluster/v3/cluster.proto @@ -20,6 +20,7 @@ import "google/protobuf/struct.proto"; import "google/protobuf/wrappers.proto"; import "envoy/annotations/deprecation.proto"; +import "udpa/annotations/security.proto"; import "udpa/annotations/status.proto"; import "udpa/annotations/versioning.proto"; import "validate/validate.proto"; @@ -582,7 +583,8 @@ message Cluster { // Soft limit on size of the cluster’s connections read and write buffers. If // unspecified, an implementation defined default is applied (1MiB). - google.protobuf.UInt32Value per_connection_buffer_limit_bytes = 5; + google.protobuf.UInt32Value per_connection_buffer_limit_bytes = 5 + [(udpa.annotations.security).configure_for_untrusted_upstream = true]; // The :ref:`load balancer type ` to use // when picking a host in the cluster. @@ -633,7 +635,8 @@ message Cluster { // supports prior knowledge for upstream connections. Even if TLS is used // with ALPN, `http2_protocol_options` must be specified. As an aside this allows HTTP/2 // connections to happen over plain text. - core.v3.Http2ProtocolOptions http2_protocol_options = 14; + core.v3.Http2ProtocolOptions http2_protocol_options = 14 + [(udpa.annotations.security).configure_for_untrusted_upstream = true]; // The extension_protocol_options field is used to provide extension-specific protocol options // for upstream connections. The key should match the extension filter name, such as diff --git a/generated_api_shadow/envoy/config/cluster/v4alpha/cluster.proto b/generated_api_shadow/envoy/config/cluster/v4alpha/cluster.proto index 2b044b2c6437..eab2f2d80fcb 100644 --- a/generated_api_shadow/envoy/config/cluster/v4alpha/cluster.proto +++ b/generated_api_shadow/envoy/config/cluster/v4alpha/cluster.proto @@ -19,6 +19,7 @@ import "google/protobuf/struct.proto"; import "google/protobuf/wrappers.proto"; import "envoy/annotations/deprecation.proto"; +import "udpa/annotations/security.proto"; import "udpa/annotations/status.proto"; import "udpa/annotations/versioning.proto"; import "validate/validate.proto"; @@ -585,7 +586,8 @@ message Cluster { // Soft limit on size of the cluster’s connections read and write buffers. If // unspecified, an implementation defined default is applied (1MiB). - google.protobuf.UInt32Value per_connection_buffer_limit_bytes = 5; + google.protobuf.UInt32Value per_connection_buffer_limit_bytes = 5 + [(udpa.annotations.security).configure_for_untrusted_upstream = true]; // The :ref:`load balancer type ` to use // when picking a host in the cluster. @@ -636,7 +638,8 @@ message Cluster { // supports prior knowledge for upstream connections. Even if TLS is used // with ALPN, `http2_protocol_options` must be specified. As an aside this allows HTTP/2 // connections to happen over plain text. - core.v4alpha.Http2ProtocolOptions http2_protocol_options = 14; + core.v4alpha.Http2ProtocolOptions http2_protocol_options = 14 + [(udpa.annotations.security).configure_for_untrusted_upstream = true]; // The extension_protocol_options field is used to provide extension-specific protocol options // for upstream connections. The key should match the extension filter name, such as diff --git a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index 8efa78bf0eb9..1362850f0530 100644 --- a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -19,6 +19,7 @@ import "google/protobuf/struct.proto"; import "google/protobuf/wrappers.proto"; import "envoy/annotations/deprecation.proto"; +import "udpa/annotations/security.proto"; import "udpa/annotations/status.proto"; import "udpa/annotations/versioning.proto"; import "validate/validate.proto"; @@ -283,13 +284,15 @@ message HttpConnectionManager { // Additional settings for HTTP requests handled by the connection manager. These will be // applicable to both HTTP1 and HTTP2 requests. - config.core.v3.HttpProtocolOptions common_http_protocol_options = 35; + config.core.v3.HttpProtocolOptions common_http_protocol_options = 35 + [(udpa.annotations.security).configure_for_untrusted_downstream = true]; // Additional HTTP/1 settings that are passed to the HTTP/1 codec. config.core.v3.Http1ProtocolOptions http_protocol_options = 8; // Additional HTTP/2 settings that are passed directly to the HTTP/2 codec. - config.core.v3.Http2ProtocolOptions http2_protocol_options = 9; + config.core.v3.Http2ProtocolOptions http2_protocol_options = 9 + [(udpa.annotations.security).configure_for_untrusted_downstream = true]; // An optional override that the connection manager will write to the server // header in responses. If not set, the default is *envoy*. @@ -334,13 +337,15 @@ message HttpConnectionManager { // // A value of 0 will completely disable the connection manager stream idle // timeout, although per-route idle timeout overrides will continue to apply. - google.protobuf.Duration stream_idle_timeout = 24; + google.protobuf.Duration stream_idle_timeout = 24 + [(udpa.annotations.security).configure_for_untrusted_downstream = true]; // The amount of time that Envoy will wait for the entire request to be received. // The timer is activated when the request is initiated, and is disarmed when the last byte of the // request is sent upstream (i.e. all decoding filters have processed the request), OR when the // response is initiated. If not specified or set to 0, this timeout is disabled. - google.protobuf.Duration request_timeout = 28; + google.protobuf.Duration request_timeout = 28 + [(udpa.annotations.security).configure_for_untrusted_downstream = true]; // The time that Envoy will wait between sending an HTTP/2 “shutdown // notification” (GOAWAY frame with max stream ID) and a final GOAWAY frame. @@ -396,7 +401,8 @@ message HttpConnectionManager { // :ref:`config_http_conn_man_headers_x-forwarded-for`, // :ref:`config_http_conn_man_headers_x-envoy-internal`, and // :ref:`config_http_conn_man_headers_x-envoy-external-address` for more information. - google.protobuf.BoolValue use_remote_address = 14; + google.protobuf.BoolValue use_remote_address = 14 + [(udpa.annotations.security).configure_for_untrusted_downstream = true]; // The number of additional ingress proxy hops from the right side of the // :ref:`config_http_conn_man_headers_x-forwarded-for` HTTP header to trust when diff --git a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto index 482bb5ed95e9..f5e6619dee33 100644 --- a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto +++ b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto @@ -19,6 +19,7 @@ import "google/protobuf/struct.proto"; import "google/protobuf/wrappers.proto"; import "envoy/annotations/deprecation.proto"; +import "udpa/annotations/security.proto"; import "udpa/annotations/status.proto"; import "udpa/annotations/versioning.proto"; import "validate/validate.proto"; @@ -281,13 +282,15 @@ message HttpConnectionManager { // Additional settings for HTTP requests handled by the connection manager. These will be // applicable to both HTTP1 and HTTP2 requests. - config.core.v4alpha.HttpProtocolOptions common_http_protocol_options = 35; + config.core.v4alpha.HttpProtocolOptions common_http_protocol_options = 35 + [(udpa.annotations.security).configure_for_untrusted_downstream = true]; // Additional HTTP/1 settings that are passed to the HTTP/1 codec. config.core.v4alpha.Http1ProtocolOptions http_protocol_options = 8; // Additional HTTP/2 settings that are passed directly to the HTTP/2 codec. - config.core.v4alpha.Http2ProtocolOptions http2_protocol_options = 9; + config.core.v4alpha.Http2ProtocolOptions http2_protocol_options = 9 + [(udpa.annotations.security).configure_for_untrusted_downstream = true]; // An optional override that the connection manager will write to the server // header in responses. If not set, the default is *envoy*. @@ -332,13 +335,15 @@ message HttpConnectionManager { // // A value of 0 will completely disable the connection manager stream idle // timeout, although per-route idle timeout overrides will continue to apply. - google.protobuf.Duration stream_idle_timeout = 24; + google.protobuf.Duration stream_idle_timeout = 24 + [(udpa.annotations.security).configure_for_untrusted_downstream = true]; // The amount of time that Envoy will wait for the entire request to be received. // The timer is activated when the request is initiated, and is disarmed when the last byte of the // request is sent upstream (i.e. all decoding filters have processed the request), OR when the // response is initiated. If not specified or set to 0, this timeout is disabled. - google.protobuf.Duration request_timeout = 28; + google.protobuf.Duration request_timeout = 28 + [(udpa.annotations.security).configure_for_untrusted_downstream = true]; // The time that Envoy will wait between sending an HTTP/2 “shutdown // notification” (GOAWAY frame with max stream ID) and a final GOAWAY frame. @@ -394,7 +399,8 @@ message HttpConnectionManager { // :ref:`config_http_conn_man_headers_x-forwarded-for`, // :ref:`config_http_conn_man_headers_x-envoy-internal`, and // :ref:`config_http_conn_man_headers_x-envoy-external-address` for more information. - google.protobuf.BoolValue use_remote_address = 14; + google.protobuf.BoolValue use_remote_address = 14 + [(udpa.annotations.security).configure_for_untrusted_downstream = true]; // The number of additional ingress proxy hops from the right side of the // :ref:`config_http_conn_man_headers_x-forwarded-for` HTTP header to trust when diff --git a/tools/protodoc/BUILD b/tools/protodoc/BUILD index 256316f2a18c..51bb3a9fbde9 100644 --- a/tools/protodoc/BUILD +++ b/tools/protodoc/BUILD @@ -1,8 +1,11 @@ load("@rules_python//python:defs.bzl", "py_binary") load("@protodoc_pip3//:requirements.bzl", "requirement") +load("//bazel:envoy_build_system.bzl", "envoy_package", "envoy_proto_library") licenses(["notice"]) # Apache 2 +envoy_package() + py_binary( name = "generate_empty", srcs = ["generate_empty.py"], @@ -10,12 +13,18 @@ py_binary( deps = [":protodoc"], ) +envoy_proto_library( + name = "manifest_proto", + srcs = ["manifest.proto"], +) + py_binary( name = "protodoc", srcs = ["protodoc.py"], - data = ["//docs:edge_defaults_manifest.yaml"], + data = ["//docs:protodoc_manifest.yaml"], visibility = ["//visibility:public"], deps = [ + ":manifest_proto_py_proto", "//tools/api_proto_plugin", "//tools/config_validation:validate_fragment", "@com_envoyproxy_protoc_gen_validate//validate:validate_py", diff --git a/tools/protodoc/manifest.proto b/tools/protodoc/manifest.proto new file mode 100644 index 000000000000..4757c76a8c10 --- /dev/null +++ b/tools/protodoc/manifest.proto @@ -0,0 +1,29 @@ +syntax = "proto3"; + +package tools.protodoc; + +import "google/protobuf/struct.proto"; + +// Additional structure information consumed by protodoc when generating +// documentation for a field. +message Description { + message EdgeConfiguration { + // Example secure edge default for the field. + google.protobuf.Value example = 1; + + // Additional note to include in the configuration warning. + string note = 2; + } + + // Additional information for when this field is used in edge deployments. + EdgeConfiguration edge_config = 1; + + // TODO: add additional information here to reflect things like Envoy + // implementation status. +} + +message Manifest { + // Map from fully qualified field name to additional information to be used in + // protodoc generation. + map fields = 1; +} diff --git a/tools/protodoc/protodoc.py b/tools/protodoc/protodoc.py index 750ca3cd78d1..c96f7cafa6c9 100755 --- a/tools/protodoc/protodoc.py +++ b/tools/protodoc/protodoc.py @@ -12,6 +12,7 @@ import string import sys +from google.protobuf import json_format from bazel_tools.tools.python.runfiles import runfiles import yaml @@ -27,6 +28,7 @@ from tools.api_proto_plugin import visitor from tools.config_validation import validate_fragment +from tools.protodoc import manifest_pb2 from udpa.annotations import security_pb2 from udpa.annotations import status_pb2 from validate import validate_pb2 @@ -401,7 +403,7 @@ def FormatAnchor(label): return '.. _%s:\n\n' % label -def FormatSecurityOptions(security_option, field, type_context, edge_default_yaml): +def FormatSecurityOptions(security_option, field, type_context, edge_config): sections = [] if security_option.configure_for_untrusted_downstream: @@ -410,10 +412,13 @@ def FormatSecurityOptions(security_option, field, type_context, edge_default_yam if security_option.configure_for_untrusted_upstream: sections.append( Indent(4, 'This field should be configured in the presence of untrusted *upstreams*.')) + if edge_config.note: + sections.append(Indent(4, edge_config.note)) - validate_fragment.ValidateFragment(field.type_name[1:], edge_default_yaml) + example_dict = json_format.MessageToDict(edge_config.example) + validate_fragment.ValidateFragment(field.type_name[1:], example_dict) field_name = type_context.name.split('.')[-1] - example = {field_name: edge_default_yaml} + example = {field_name: example_dict} sections.append( Indent(4, 'Example configuration for untrusted environments:\n\n') + Indent(4, '.. code-block:: yaml\n\n') + @@ -423,14 +428,14 @@ def FormatSecurityOptions(security_option, field, type_context, edge_default_yam return '.. attention::\n' + '\n\n'.join(sections) -def FormatFieldAsDefinitionListItem(outer_type_context, type_context, field, - edge_defaults_manifest): +def FormatFieldAsDefinitionListItem(outer_type_context, type_context, field, protodoc_manifest): """Format a FieldDescriptorProto as RST definition list item. Args: outer_type_context: contextual information for enclosing message. type_context: contextual information for message/enum/field. field: FieldDescriptorProto. + protodoc_manifest: tools.protodoc.Manifest for proto. Returns: RST formatted definition list item. @@ -479,11 +484,12 @@ def FormatFieldAsDefinitionListItem(outer_type_context, type_context, field, # If there is a udpa.annotations.security option, include it after the comment. if field.options.HasExtension(security_pb2.security): - edge_default_yaml = edge_defaults_manifest.get(type_context.name) - if not edge_default_yaml: - raise ProtodocError('Missing edge default YAML example for %s' % type_context.name) + manifest_description = protodoc_manifest.fields.get(type_context.name) + if not manifest_description: + raise ProtodocError('Missing protodoc manifest YAML for %s' % type_context.name) formatted_security_options = FormatSecurityOptions( - field.options.Extensions[security_pb2.security], field, type_context, edge_default_yaml) + field.options.Extensions[security_pb2.security], field, type_context, + manifest_description.edge_config) else: formatted_security_options = '' @@ -493,12 +499,13 @@ def FormatFieldAsDefinitionListItem(outer_type_context, type_context, field, Indent, 2), comment + formatted_oneof_comment) + formatted_security_options -def FormatMessageAsDefinitionList(type_context, msg, edge_defaults_manifest): +def FormatMessageAsDefinitionList(type_context, msg, protodoc_manifest): """Format a DescriptorProto as RST definition list. Args: type_context: contextual information for message/enum/field. msg: DescriptorProto. + protodoc_manifest: tools.protodoc.Manifest for proto. Returns: RST formatted definition list item. @@ -518,7 +525,7 @@ def FormatMessageAsDefinitionList(type_context, msg, edge_defaults_manifest): type_context.oneof_names[index] = oneof_decl.name return '\n'.join( FormatFieldAsDefinitionListItem(type_context, type_context.ExtendField(index, field.name), - field, edge_defaults_manifest) + field, protodoc_manifest) for index, field in enumerate(msg.field)) + '\n' @@ -574,8 +581,12 @@ class RstFormatVisitor(visitor.Visitor): def __init__(self): r = runfiles.Create() - with open(r.Rlocation('envoy/docs/edge_defaults_manifest.yaml'), 'r') as f: - self.edge_defaults_manifest = yaml.load(f.read()) + with open(r.Rlocation('envoy/docs/protodoc_manifest.yaml'), 'r') as f: + # Load as YAML, emit as JSON and then parse as proto to provide type + # checking. + protodoc_manifest_untyped = yaml.load(f.read()) + self.protodoc_manifest = manifest_pb2.Manifest() + json_format.Parse(json.dumps(protodoc_manifest_untyped), self.protodoc_manifest) def VisitEnum(self, enum_proto, type_context): normal_enum_type = NormalizeTypeContextName(type_context.name) @@ -606,7 +617,7 @@ def VisitMessage(self, msg_proto, type_context, nested_msgs, nested_enums): return anchor + header + proto_link + formatted_leading_comment + FormatMessageAsJson( type_context, msg_proto) + FormatMessageAsDefinitionList( type_context, msg_proto, - self.edge_defaults_manifest) + '\n'.join(nested_msgs) + '\n' + '\n'.join(nested_enums) + self.protodoc_manifest) + '\n'.join(nested_msgs) + '\n' + '\n'.join(nested_enums) def VisitFile(self, file_proto, type_context, services, msgs, enums): has_messages = True