diff --git a/api/BUILD b/api/BUILD index 7bf42e6d27e71..3587102474dda 100644 --- a/api/BUILD +++ b/api/BUILD @@ -285,12 +285,23 @@ proto_library( ], ) +proto_library( + name = "xds_protos", + visibility = ["//visibility:public"], + deps = [ + "@com_github_cncf_udpa//xds/core/v3:pkg", + "@com_github_cncf_udpa//xds/type/matcher/v3:pkg", + "@com_github_cncf_udpa//xds/type/v3:pkg", + ], +) + proto_library( name = "all_protos", visibility = ["//visibility:public"], deps = [ ":v2_protos", ":v3_protos", + ":xds_protos", ], ) diff --git a/api/bazel/repository_locations.bzl b/api/bazel/repository_locations.bzl index c94cbc3b48cb6..98fa8906b1dec 100644 --- a/api/bazel/repository_locations.bzl +++ b/api/bazel/repository_locations.bzl @@ -33,9 +33,9 @@ REPOSITORY_LOCATIONS_SPEC = dict( project_desc = "xDS API Working Group (xDS-WG)", project_url = "https://github.com/cncf/xds", # During the UDPA -> xDS migration, we aren't working with releases. - version = "0fa49ea1db0ccf084453766a755b2e76434d99fc", - sha256 = "9369c65e20201ea43e2c293cf024f58167dd727d864706481972ccdf3aacdaab", - release_date = "2022-01-12", + version = "7f1daf1720fc185f3b63f70d25aefaeef83d88d7", + sha256 = "62c0daaff43fd9a62c280bf2b0c2b670372b24377ea5e9ea4302cf748dd53cba", + release_date = "2022-03-14", strip_prefix = "xds-{version}", urls = ["https://github.com/cncf/xds/archive/{version}.tar.gz"], use_category = ["api"], diff --git a/api/envoy/extensions/matching/common_inputs/network/v3/network_inputs.proto b/api/envoy/extensions/matching/common_inputs/network/v3/network_inputs.proto index 8f54d34587026..1a8da1c875ce2 100644 --- a/api/envoy/extensions/matching/common_inputs/network/v3/network_inputs.proto +++ b/api/envoy/extensions/matching/common_inputs/network/v3/network_inputs.proto @@ -13,18 +13,22 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#protodoc-title: Common Network Matching Inputs] // Specifies that matching should be performed by the destination IP address. +// [#extension: envoy.matching.inputs.destination_ip] message DestinationIPInput { } // Specifies that matching should be performed by the destination port. +// [#extension: envoy.matching.inputs.destination_port] message DestinationPortInput { } // Specifies that matching should be performed by the source IP address. +// [#extension: envoy.matching.inputs.source_ip] message SourceIPInput { } // Specifies that matching should be performed by the source port. +// [#extension: envoy.matching.inputs.source_port] message SourcePortInput { } @@ -32,6 +36,7 @@ message SourcePortInput { // will only be different from the source IP address when using a listener // filter that overrides the source address, such as the :ref:`Proxy Protocol // listener filter `). +// [#extension: envoy.matching.inputs.direct_source_ip] message DirectSourceIPInput { } @@ -39,6 +44,7 @@ message DirectSourceIPInput { // Specifies the source IP match type. The values include: // // * ``local`` - matches a connection originating from the same host, +// [#extension: envoy.matching.inputs.source_type] message SourceTypeInput { } @@ -46,6 +52,7 @@ message SourceTypeInput { // // :ref:`TLS Inspector ` provides the requested server name based on SNI, // when TLS protocol is detected. +// [#extension: envoy.matching.inputs.server_name] message ServerNameInput { } @@ -56,6 +63,7 @@ message ServerNameInput { // * ``raw_buffer`` - default, used when no transport protocol is detected, // * ``tls`` - set by :ref:`envoy.filters.listener.tls_inspector ` // when TLS protocol is detected. +// [#extension: envoy.matching.inputs.transport_protocol] message TransportProtocolInput { } @@ -84,5 +92,6 @@ message TransportProtocolInput { // However, the use of ALPN is pretty much limited to the HTTP/2 traffic on the Internet, // and matching on values other than ``h2`` is going to lead to a lot of false negatives, // unless all connecting clients are known to use ALPN. +// [#extension: envoy.matching.inputs.application_protocol] message ApplicationProtocolInput { } diff --git a/api/envoy/type/matcher/v3/http_inputs.proto b/api/envoy/type/matcher/v3/http_inputs.proto index 36e12a81fdc7f..68ce45030ec74 100644 --- a/api/envoy/type/matcher/v3/http_inputs.proto +++ b/api/envoy/type/matcher/v3/http_inputs.proto @@ -18,6 +18,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // e.g. if the request contains two 'foo' headers with value 'bar' and 'baz', the input // string will be 'bar,baz'. // [#comment:TODO(snowp): Link to unified matching docs.] +// [#extension: envoy.matching.inputs.request_headers] message HttpRequestHeaderMatchInput { // The request header to match on. string header_name = 1 @@ -29,6 +30,7 @@ message HttpRequestHeaderMatchInput { // e.g. if the request contains two 'foo' headers with value 'bar' and 'baz', the input // string will be 'bar,baz'. // [#comment:TODO(snowp): Link to unified matching docs.] +// [#extension: envoy.matching.inputs.request_trailers] message HttpRequestTrailerMatchInput { // The request trailer to match on. string header_name = 1 @@ -40,6 +42,7 @@ message HttpRequestTrailerMatchInput { // e.g. if the response contains two 'foo' headers with value 'bar' and 'baz', the input // string will be 'bar,baz'. // [#comment:TODO(snowp): Link to unified matching docs.] +// [#extension: envoy.matching.inputs.response_headers] message HttpResponseHeaderMatchInput { // The response header to match on. string header_name = 1 @@ -51,6 +54,7 @@ message HttpResponseHeaderMatchInput { // e.g. if the request contains two 'foo' headers with value 'bar' and 'baz', the input // string will be 'bar,baz'. // [#comment:TODO(snowp): Link to unified matching docs.] +// [#extension: envoy.matching.inputs.response_trailers] message HttpResponseTrailerMatchInput { // The response trailer to match on. string header_name = 1 diff --git a/docs/BUILD b/docs/BUILD index a12a4e92f00a3..ca5e57fcf0d9c 100644 --- a/docs/BUILD +++ b/docs/BUILD @@ -104,6 +104,12 @@ genquery( scope = ["@envoy_api//:v3_protos"], ) +genquery( + name = "xds_proto_srcs", + expression = "labels(srcs, labels(deps, @envoy_api//:xds_protos))", + scope = ["@envoy_api//:xds_protos"], +) + genrule( name = "empty_protos_rst", srcs = [":empty_extensions.json"], @@ -129,6 +135,20 @@ genrule( tools = ["//tools/docs:generate_api_rst"], ) +genrule( + name = "xds_rst", + srcs = [ + "//tools/protodoc:xds_protodoc", + ":xds_proto_srcs", + ], + outs = ["xds_rst.tar"], + cmd = """ + $(location //tools/docs:generate_api_rst) \\ + $(location xds_proto_srcs) $(locations //tools/protodoc:xds_protodoc) $@ + """, + tools = ["//tools/docs:generate_api_rst"], +) + pkg_files( name = "sphinx_base", srcs = glob( @@ -179,6 +199,7 @@ pkg_tar( ":empty_protos_rst", ":extensions_security_rst", ":external_deps_rst", + ":xds_rst", ], ) diff --git a/docs/root/api-v3/common_messages/common_messages.rst b/docs/root/api-v3/common_messages/common_messages.rst index b15806e056e9f..e4e126e6912cd 100644 --- a/docs/root/api-v3/common_messages/common_messages.rst +++ b/docs/root/api-v3/common_messages/common_messages.rst @@ -33,3 +33,18 @@ Common messages ../extensions/matching/input_matchers/ip/v3/ip.proto ../extensions/matching/common_inputs/environment_variable/v3/input.proto ../extensions/matching/common_inputs/network/v3/network_inputs.proto + ../../xds/type/v3/range.proto + ../../xds/type/v3/typed_struct.proto + ../../xds/type/matcher/v3/ip.proto + ../../xds/type/matcher/v3/matcher.proto + ../../xds/type/matcher/v3/range.proto + ../../xds/type/matcher/v3/regex.proto + ../../xds/type/matcher/v3/string.proto + ../../xds/core/v3/authority.proto + ../../xds/core/v3/cidr.proto + ../../xds/core/v3/collection_entry.proto + ../../xds/core/v3/context_params.proto + ../../xds/core/v3/extension.proto + ../../xds/core/v3/resource.proto + ../../xds/core/v3/resource_locator.proto + ../../xds/core/v3/resource_name.proto diff --git a/docs/root/intro/arch_overview/advanced/matching/matching_api.rst b/docs/root/intro/arch_overview/advanced/matching/matching_api.rst index 9ae4b1c685851..efc9d4e231a7b 100644 --- a/docs/root/intro/arch_overview/advanced/matching/matching_api.rst +++ b/docs/root/intro/arch_overview/advanced/matching/matching_api.rst @@ -16,6 +16,59 @@ better performance than the linear list matching as seen in Envoy's HTTP routing use of extension points to make it easy to extend to different inputs based on protocol or environment data as well as custom sublinear matchers and direct matchers. +Inputs and Matching Algorithms +############################## + +Matching inputs define a way to extract the input value used for matching. +The input functions are context-sensitive. For example, HTTP header inputs are +applicable only in HTTP contexts, e.g. for matching HTTP requests. + +.. _extension_category_envoy.matching.http.input: + +HTTP Input Functions +******************** + +These input functions are available for matching HTTP requests: + +* :ref:`Request header value `. +* :ref:`Request trailer value `. +* :ref:`Response header value `. +* :ref:`Response trailer value `. + +.. _extension_category_envoy.matching.network.input: + +Network Input Functions +*********************** + +These input functions are available for matching TCP connections: + +* :ref:`Destination IP `. +* :ref:`Destination port `. +* :ref:`Source IP `. +* :ref:`Direct source IP `. +* :ref:`Source port `. +* :ref:`Source type `. +* :ref:`Server name `. +* :ref:`Transport protocol `. +* :ref:`Application protocol `. + +Common Input Functons +********************* + +These input functions are available in any context: + +* :ref:`Environment variable `. + +Custom Matching Algorithms +************************** + +In addition to the built-in exact and prefix matchers, these custom matchers +are available in some contexts: + +.. _extension_envoy.matching.custom_matchers.trie_matcher: + +* :ref:`Trie-based IP matcher ` applies to network inputs. + Filter Integration ################## diff --git a/source/common/http/matching/inputs.h b/source/common/http/matching/inputs.h index 551cab256fb75..947707874f277 100644 --- a/source/common/http/matching/inputs.h +++ b/source/common/http/matching/inputs.h @@ -51,7 +51,7 @@ class HttpHeadersDataInputFactoryBase : public Matcher::DataInputFactory createDataInputFactoryCb(const Protobuf::Message& config, @@ -85,7 +85,7 @@ class HttpRequestHeadersDataInputFactory : public HttpHeadersDataInputFactoryBase< HttpRequestHeadersDataInput, envoy::type::matcher::v3::HttpRequestHeaderMatchInput> { public: - HttpRequestHeadersDataInputFactory() : HttpHeadersDataInputFactoryBase("request-headers") {} + HttpRequestHeadersDataInputFactory() : HttpHeadersDataInputFactoryBase("request_headers") {} }; class HttpResponseHeadersDataInput : public HttpHeadersDataInputBase { @@ -102,7 +102,7 @@ class HttpResponseHeadersDataInputFactory : public HttpHeadersDataInputFactoryBase< HttpResponseHeadersDataInput, envoy::type::matcher::v3::HttpResponseHeaderMatchInput> { public: - HttpResponseHeadersDataInputFactory() : HttpHeadersDataInputFactoryBase("response-headers") {} + HttpResponseHeadersDataInputFactory() : HttpHeadersDataInputFactoryBase("response_headers") {} }; class HttpRequestTrailersDataInput : public HttpHeadersDataInputBase { @@ -119,7 +119,7 @@ class HttpRequestTrailersDataInputFactory : public HttpHeadersDataInputFactoryBase< HttpRequestTrailersDataInput, envoy::type::matcher::v3::HttpRequestTrailerMatchInput> { public: - HttpRequestTrailersDataInputFactory() : HttpHeadersDataInputFactoryBase("request-trailers") {} + HttpRequestTrailersDataInputFactory() : HttpHeadersDataInputFactoryBase("request_trailers") {} }; class HttpResponseTrailersDataInput : public HttpHeadersDataInputBase { @@ -137,7 +137,7 @@ class HttpResponseTrailersDataInputFactory : public HttpHeadersDataInputFactoryBase< HttpRequestTrailersDataInput, envoy::type::matcher::v3::HttpRequestTrailerMatchInput> { public: - HttpResponseTrailersDataInputFactory() : HttpHeadersDataInputFactoryBase("response-trailers") {} + HttpResponseTrailersDataInputFactory() : HttpHeadersDataInputFactoryBase("response_trailers") {} }; } // namespace Matching } // namespace Http diff --git a/source/common/network/matching/inputs.h b/source/common/network/matching/inputs.h index 20bb872e36edf..9e74d8ca890db 100644 --- a/source/common/network/matching/inputs.h +++ b/source/common/network/matching/inputs.h @@ -15,7 +15,7 @@ class BaseFactory : public Matcher::DataInputFactory { explicit BaseFactory(const std::string& name) : name_(name) {} public: - std::string name() const override { return name_; } + std::string name() const override { return "envoy.matching.inputs." + name_; } Matcher::DataInputFactoryCb createDataInputFactoryCb(const Protobuf::Message&, ProtobufMessage::ValidationVisitor&) override { @@ -39,7 +39,7 @@ class DestinationIPInputFactory DestinationIPInput, envoy::extensions::matching::common_inputs::network::v3::DestinationIPInput> { public: - DestinationIPInputFactory() : BaseFactory("destination-ip") {} + DestinationIPInputFactory() : BaseFactory("destination_ip") {} }; class DestinationPortInput : public Matcher::DataInput { @@ -52,7 +52,7 @@ class DestinationPortInputFactory DestinationPortInput, envoy::extensions::matching::common_inputs::network::v3::DestinationPortInput> { public: - DestinationPortInputFactory() : BaseFactory("destination-port") {} + DestinationPortInputFactory() : BaseFactory("destination_port") {} }; class SourceIPInput : public Matcher::DataInput { @@ -64,7 +64,7 @@ class SourceIPInputFactory : public BaseFactory { public: - SourceIPInputFactory() : BaseFactory("source-ip") {} + SourceIPInputFactory() : BaseFactory("source_ip") {} }; class SourcePortInput : public Matcher::DataInput { @@ -76,7 +76,7 @@ class SourcePortInputFactory : public BaseFactory { public: - SourcePortInputFactory() : BaseFactory("source-port") {} + SourcePortInputFactory() : BaseFactory("source_port") {} }; class DirectSourceIPInput : public Matcher::DataInput { @@ -89,7 +89,7 @@ class DirectSourceIPInputFactory DirectSourceIPInput, envoy::extensions::matching::common_inputs::network::v3::DirectSourceIPInput> { public: - DirectSourceIPInputFactory() : BaseFactory("direct-source-ip") {} + DirectSourceIPInputFactory() : BaseFactory("direct_source_ip") {} }; class SourceTypeInput : public Matcher::DataInput { @@ -101,7 +101,7 @@ class SourceTypeInputFactory : public BaseFactory { public: - SourceTypeInputFactory() : BaseFactory("source-type") {} + SourceTypeInputFactory() : BaseFactory("source_type") {} }; class ServerNameInput : public Matcher::DataInput { @@ -113,7 +113,7 @@ class ServerNameInputFactory : public BaseFactory { public: - ServerNameInputFactory() : BaseFactory("server-name") {} + ServerNameInputFactory() : BaseFactory("server_name") {} }; class TransportProtocolInput : public Matcher::DataInput { @@ -126,7 +126,7 @@ class TransportProtocolInputFactory TransportProtocolInput, envoy::extensions::matching::common_inputs::network::v3::TransportProtocolInput> { public: - TransportProtocolInputFactory() : BaseFactory("transport-protocol") {} + TransportProtocolInputFactory() : BaseFactory("transport_protocol") {} }; class ApplicationProtocolInput : public Matcher::DataInput { @@ -139,7 +139,7 @@ class ApplicationProtocolInputFactory ApplicationProtocolInput, envoy::extensions::matching::common_inputs::network::v3::ApplicationProtocolInput> { public: - ApplicationProtocolInputFactory() : BaseFactory("application-protocol") {} + ApplicationProtocolInputFactory() : BaseFactory("application_protocol") {} }; } // namespace Matching diff --git a/source/extensions/common/matcher/BUILD b/source/extensions/common/matcher/BUILD index c783a68487384..a4b96c3f92bfa 100644 --- a/source/extensions/common/matcher/BUILD +++ b/source/extensions/common/matcher/BUILD @@ -1,5 +1,6 @@ load( "//bazel:envoy_build_system.bzl", + "envoy_cc_extension", "envoy_cc_library", "envoy_extension_package", ) @@ -20,7 +21,7 @@ envoy_cc_library( ], ) -envoy_cc_library( +envoy_cc_extension( name = "trie_matcher_lib", srcs = ["trie_matcher.cc"], hdrs = ["trie_matcher.h"], diff --git a/source/extensions/common/matcher/trie_matcher.h b/source/extensions/common/matcher/trie_matcher.h index 7a327fde97df3..e71575960d1fc 100644 --- a/source/extensions/common/matcher/trie_matcher.h +++ b/source/extensions/common/matcher/trie_matcher.h @@ -150,7 +150,7 @@ class TrieMatcherFactoryBase : public ::Envoy::Matcher::CustomMatcherFactory(); } - std::string name() const override { return "trie-matcher"; } + std::string name() const override { return "envoy.matching.custom_matchers.trie_matcher"; } }; class NetworkTrieMatcherFactory : public TrieMatcherFactoryBase {}; diff --git a/source/extensions/extensions_build_config.bzl b/source/extensions/extensions_build_config.bzl index 068f98e63f27b..9bf7950e20ed0 100644 --- a/source/extensions/extensions_build_config.bzl +++ b/source/extensions/extensions_build_config.bzl @@ -329,6 +329,12 @@ EXTENSIONS = { # apple DNS resolver extension is only needed in MacOS build plus one want to use apple library for DNS resolving. "envoy.network.dns_resolver.apple": "//source/extensions/network/dns_resolver/apple:config", + + # + # Custom matchers + # + + "envoy.matching.custom_matchers.trie_matcher": "//source/extensions/common/matcher:trie_matcher_lib", } # These can be changed to ["//visibility:public"], for downstream builds which diff --git a/source/extensions/extensions_metadata.yaml b/source/extensions/extensions_metadata.yaml index bbd0eb1d956f2..21722c02f5198 100644 --- a/source/extensions/extensions_metadata.yaml +++ b/source/extensions/extensions_metadata.yaml @@ -750,3 +750,73 @@ envoy.http.stateful_session.cookie: - envoy.http.stateful_session security_posture: unknown status: alpha +envoy.matching.inputs.request_headers: + categories: + - envoy.matching.http.input + security_posture: unknown + status: alpha +envoy.matching.inputs.request_trailers: + categories: + - envoy.matching.http.input + security_posture: unknown + status: alpha +envoy.matching.inputs.response_headers: + categories: + - envoy.matching.http.input + security_posture: unknown + status: alpha +envoy.matching.inputs.response_trailers: + categories: + - envoy.matching.http.input + security_posture: unknown + status: alpha +envoy.matching.inputs.destination_ip: + categories: + - envoy.matching.network.input + security_posture: unknown + status: alpha +envoy.matching.inputs.destination_port: + categories: + - envoy.matching.network.input + security_posture: unknown + status: alpha +envoy.matching.inputs.source_ip: + categories: + - envoy.matching.network.input + security_posture: unknown + status: alpha +envoy.matching.inputs.source_port: + categories: + - envoy.matching.network.input + security_posture: unknown + status: alpha +envoy.matching.inputs.direct_source_ip: + categories: + - envoy.matching.network.input + security_posture: unknown + status: alpha +envoy.matching.inputs.source_type: + categories: + - envoy.matching.network.input + security_posture: unknown + status: alpha +envoy.matching.inputs.server_name: + categories: + - envoy.matching.network.input + security_posture: unknown + status: alpha +envoy.matching.inputs.transport_protocol: + categories: + - envoy.matching.network.input + security_posture: unknown + status: alpha +envoy.matching.inputs.application_protocol: + categories: + - envoy.matching.network.input + security_posture: unknown + status: alpha +envoy.matching.custom_matchers.trie_matcher: + categories: + - envoy.matching.network.custom_matchers + security_posture: unknown + status: alpha diff --git a/tools/api_proto_plugin/plugin.py b/tools/api_proto_plugin/plugin.py index c90a125cd7389..9a3958bbd07a8 100644 --- a/tools/api_proto_plugin/plugin.py +++ b/tools/api_proto_plugin/plugin.py @@ -66,7 +66,9 @@ def plugin(output_descriptors): f = response.file.add() f.name = file_proto.name + od.output_suffix # Don't run API proto plugins on things like WKT types etc. - if not file_proto.package.startswith('envoy.'): + envoy_proto = file_proto.package.startswith('envoy.') or file_proto.package.startswith( + 'xds.') + if not envoy_proto: continue if request.HasField("parameter") and od.want_params: params = dict(param.split('=') for param in request.parameter.split(',')) diff --git a/tools/docs/generate_api_rst.py b/tools/docs/generate_api_rst.py index ae38c4ea91d82..060278bc18d35 100644 --- a/tools/docs/generate_api_rst.py +++ b/tools/docs/generate_api_rst.py @@ -42,9 +42,13 @@ def main(): ] for rst_file_path in envoy_api_rst_files: + root = "api-v3" canonical = include_package(envoy_api_protos, rst_file_path, "envoy/") if canonical is None: canonical = include_package(envoy_api_protos, rst_file_path, "contrib/envoy/") + if canonical is None: + canonical = include_package(envoy_api_protos, rst_file_path, "xds/") + root = "xds" if canonical is None: continue @@ -52,7 +56,7 @@ def main(): if os.path.getsize(rst_file_path) == 0: continue - target = os.path.join("rst-out/api-v3", canonical) + target = os.path.join("rst-out", root, canonical) if not os.path.exists(os.path.dirname(target)): os.makedirs(os.path.dirname(target)) shutil.copy(rst_file_path, target) diff --git a/tools/extensions/extensions_check.py b/tools/extensions/extensions_check.py index 5cf004103eb98..de667a4eb6b7a 100644 --- a/tools/extensions/extensions_check.py +++ b/tools/extensions/extensions_check.py @@ -15,7 +15,14 @@ BUILTIN_EXTENSIONS = ( "envoy.request_id.uuid", "envoy.upstreams.tcp.generic", "envoy.transport_sockets.tls", - "envoy.upstreams.http.http_protocol_options", "envoy.upstreams.http.generic") + "envoy.upstreams.http.http_protocol_options", "envoy.upstreams.http.generic", + "envoy.matching.inputs.request_headers", "envoy.matching.inputs.request_trailers", + "envoy.matching.inputs.response_headers", "envoy.matching.inputs.response_trailers", + "envoy.matching.inputs.destination_ip", "envoy.matching.inputs.destination_port", + "envoy.matching.inputs.source_ip", "envoy.matching.inputs.source_port", + "envoy.matching.inputs.direct_source_ip", "envoy.matching.inputs.source_type", + "envoy.matching.inputs.server_name", "envoy.matching.inputs.transport_protocol", + "envoy.matching.inputs.application_protocol") # All Envoy extensions must be tagged with their security hardening stance with # respect to downstream and upstream data plane threats. These are verbose @@ -53,7 +60,9 @@ "envoy.sip_proxy.filters", "envoy.transport_sockets.downstream", "envoy.transport_sockets.upstream", "envoy.tls.cert_validator", "envoy.upstreams", "envoy.wasm.runtime", "envoy.common.key_value", "envoy.network.dns_resolver", - "envoy.rbac.matchers", "envoy.access_loggers.extension_filters", "envoy.http.stateful_session") + "envoy.rbac.matchers", "envoy.access_loggers.extension_filters", "envoy.http.stateful_session", + "envoy.matching.http.input", "envoy.matching.network.input", + "envoy.matching.network.custom_matchers") EXTENSION_STATUS_VALUES = ( # This extension is stable and is expected to be production usable. diff --git a/tools/protodoc/BUILD b/tools/protodoc/BUILD index c880490a1a268..378ee0fb76d60 100644 --- a/tools/protodoc/BUILD +++ b/tools/protodoc/BUILD @@ -46,3 +46,8 @@ protodoc_rule( name = "api_v3_protodoc", deps = ["@envoy_api//:v3_protos"], ) + +protodoc_rule( + name = "xds_protodoc", + deps = ["@envoy_api//:xds_protos"], +) diff --git a/tools/protodoc/protodoc.bzl b/tools/protodoc/protodoc.bzl index 9858d190efe28..b870b13c65785 100644 --- a/tools/protodoc/protodoc.bzl +++ b/tools/protodoc/protodoc.bzl @@ -22,7 +22,8 @@ def _protodoc_rule_impl(ctx): depset([ x for x in ctx.attr.deps[0][OutputGroupInfo].rst.to_list() - if x.short_path.startswith("../envoy_api") + if (x.short_path.startswith("../envoy_api") or + x.short_path.startswith("../com_github_cncf_udpa")) ]), ], ), diff --git a/tools/protodoc/protodoc.py b/tools/protodoc/protodoc.py index 733de2e78e41c..87cab995f7344 100755 --- a/tools/protodoc/protodoc.py +++ b/tools/protodoc/protodoc.py @@ -49,6 +49,9 @@ # Namespace prefix for RPCs. RPC_NAMESPACE_PREFIX = '.google.rpc.' +# Namespace prefix for cncf/xds top-level APIs. +CNCF_PREFIX = '.xds.' + # http://www.fileformat.info/info/unicode/char/2063/index.htm UNICODE_INVISIBLE_SEPARATOR = u'\u2063' @@ -182,6 +185,11 @@ def github_url(text, type_context): Returns: A string with a corresponding data plane API GitHub Url. """ + if type_context.name.startswith(CNCF_PREFIX[1:]): + return format_external_link( + text, + f"https://github.com/cncf/xds/blob/main/{type_context.source_code_info.name}#L{type_context.location.span[0]}" + ) return f":repo:`{text} `" @@ -428,8 +436,10 @@ def format_field_type(type_context, field): field: FieldDescriptor proto. Return: RST formatted field type. """ - if field.type_name.startswith(ENVOY_API_NAMESPACE_PREFIX) or field.type_name.startswith( - ENVOY_PREFIX): + envoy_proto = ( + field.type_name.startswith(ENVOY_API_NAMESPACE_PREFIX) + or field.type_name.startswith(ENVOY_PREFIX) or field.type_name.startswith(CNCF_PREFIX)) + if envoy_proto: type_name = normalize_field_type_name(field.type_name) if field.type == field.TYPE_MESSAGE: if type_context.map_typenames and type_name_from_fqn( diff --git a/tools/protoxform/protoxform.py b/tools/protoxform/protoxform.py index 4685774b5eedb..4866fe98f7229 100755 --- a/tools/protoxform/protoxform.py +++ b/tools/protoxform/protoxform.py @@ -45,7 +45,9 @@ def visit_file(self, file_proto, type_context, services, msgs, enums): existing_pkg_version_status = output_proto.options.Extensions[ status_pb2.file_status].package_version_status empty_file = len(services) == 0 and len(enums) == 0 and len(msgs) == 0 - pkg_version_status_exempt = file_proto.name.startswith('envoy/annotations') or empty_file + pkg_version_status_exempt = ( + file_proto.name.startswith('envoy/annotations') or empty_file + or file_proto.name.startswith('xds')) # It's a format error not to set package_version_status. if existing_pkg_version_status == status_pb2.UNKNOWN and not pkg_version_status_exempt: raise ProtoXformError('package_version_status must be set in %s' % file_proto.name) diff --git a/tools/type_whisperer/proto_build_targets_gen.py b/tools/type_whisperer/proto_build_targets_gen.py index 2da22439946f1..17bd1d70ab045 100644 --- a/tools/type_whisperer/proto_build_targets_gen.py +++ b/tools/type_whisperer/proto_build_targets_gen.py @@ -58,12 +58,23 @@ ], ) +proto_library( + name = "xds_protos", + visibility = ["//visibility:public"], + deps = [ + "@com_github_cncf_udpa//xds/core/v3:pkg", + "@com_github_cncf_udpa//xds/type/matcher/v3:pkg", + "@com_github_cncf_udpa//xds/type/v3:pkg", + ], +) + proto_library( name = "all_protos", visibility = ["//visibility:public"], deps = [ ":v2_protos", ":v3_protos", + ":xds_protos", ], )