diff --git a/api/BUILD b/api/BUILD index 7bf42e6d27e7..3587102474dd 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 c94cbc3b48cb..98fa8906b1de 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 8f54d3458702..1a8da1c875ce 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 36e12a81fdc7..68ce45030ec7 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 a12a4e92f00a..ca5e57fcf0d9 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 b15806e056e9..e4e126e6912c 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 9ae4b1c68585..efc9d4e231a7 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 551cab256fb7..947707874f27 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 20bb872e36ed..9e74d8ca890d 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 c783a6848738..a4b96c3f92bf 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 7a327fde97df..e71575960d1f 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 068f98e63f27..9bf7950e20ed 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 bbd0eb1d956f..21722c02f519 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 c90a125cd738..9a3958bbd07a 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 ae38c4ea91d8..060278bc18d3 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 5cf004103eb9..de667a4eb6b7 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 c880490a1a26..378ee0fb76d6 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 9858d190efe2..b870b13c6578 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 733de2e78e41..87cab995f734 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 4685774b5eed..4866fe98f722 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 2da22439946f..17bd1d70ab04 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", ], )