api/config: use resource type annotations to provide type-to-endpoint. (#9566)

Previously, type_to_endpoint.cc had a lot of hardcoding, which doesn't scale well with multiple API
versions. See https://github.com/envoyproxy/envoy/pull/9526 for an example of the issues
encountered.

This patch switches to using explicit resource type annotations on service descriptors, which is
great for documentation (previously this was sometimes given in comments, sometimes not), and allows
for a reflection driven reverse map from resource type URL to endpoints to be built at runtime.

Risk level: Low
Testing: New unit tests for type_to_endpoint.cc and golden protoxform tests for the new annotations.

Fixes #9454.

Signed-off-by: Harvey Tuch <htuch@google.com>

Mirrored from https://github.com/envoyproxy/envoy @ cceab393664429a3063d787cf28cade3c8ab01c7
master-ci-test
data-plane-api(CircleCI) 5 years ago
parent 47d665dff3
commit abba11d3ee
  1. 5
      envoy/annotations/BUILD
  2. 16
      envoy/annotations/resource.proto
  3. 1
      envoy/api/v2/BUILD
  4. 3
      envoy/api/v2/cds.proto
  5. 3
      envoy/api/v2/eds.proto
  6. 3
      envoy/api/v2/lds.proto
  7. 5
      envoy/api/v2/rds.proto
  8. 3
      envoy/api/v2/srds.proto
  9. 1
      envoy/service/cluster/v3alpha/BUILD
  10. 4
      envoy/service/cluster/v3alpha/cds.proto
  11. 1
      envoy/service/discovery/v2/BUILD
  12. 3
      envoy/service/discovery/v2/rtds.proto
  13. 3
      envoy/service/discovery/v2/sds.proto
  14. 1
      envoy/service/endpoint/v3alpha/BUILD
  15. 3
      envoy/service/endpoint/v3alpha/eds.proto
  16. 1
      envoy/service/listener/v3alpha/BUILD
  17. 3
      envoy/service/listener/v3alpha/lds.proto
  18. 1
      envoy/service/route/v3alpha/BUILD
  19. 5
      envoy/service/route/v3alpha/rds.proto
  20. 4
      envoy/service/route/v3alpha/srds.proto
  21. 1
      envoy/service/runtime/v3alpha/BUILD
  22. 3
      envoy/service/runtime/v3alpha/rtds.proto
  23. 1
      envoy/service/secret/v3alpha/BUILD
  24. 5
      envoy/service/secret/v3alpha/sds.proto
  25. 19
      test/validate/BUILD

@ -0,0 +1,5 @@
load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package")
licenses(["notice"]) # Apache 2
api_proto_package()

@ -0,0 +1,16 @@
syntax = "proto3";
package envoy.annotations;
import "google/protobuf/descriptor.proto";
// Magic number in this file derived from top 28bit of SHA256 digest of "envoy.annotation.resource".
extend google.protobuf.ServiceOptions {
ResourceAnnotation resource = 265073217;
}
message ResourceAnnotation {
// Annotation for xDS services that indicates the fully-qualified Protobuf type for the resource
// type.
string type = 1;
}

@ -7,6 +7,7 @@ licenses(["notice"]) # Apache 2
api_proto_package(
has_services = True,
deps = [
"//envoy/annotations:pkg",
"//envoy/api/v2/auth:pkg",
"//envoy/api/v2/cluster:pkg",
"//envoy/api/v2/core:pkg",

@ -6,6 +6,7 @@ import "envoy/api/v2/discovery.proto";
import "google/api/annotations.proto";
import "envoy/annotations/resource.proto";
import "udpa/annotations/migrate.proto";
import public "envoy/api/v2/cluster.proto";
@ -20,6 +21,8 @@ option (udpa.annotations.file_migrate).move_to_package = "envoy.service.cluster.
// Return list of all clusters this proxy will load balance to.
service ClusterDiscoveryService {
option (envoy.annotations.resource).type = "envoy.api.v2.Cluster";
rpc StreamClusters(stream DiscoveryRequest) returns (stream DiscoveryResponse) {
}

@ -8,6 +8,7 @@ import "google/api/annotations.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/wrappers.proto";
import "envoy/annotations/resource.proto";
import "udpa/annotations/migrate.proto";
import "validate/validate.proto";
@ -23,6 +24,8 @@ option (udpa.annotations.file_migrate).move_to_package = "envoy.service.endpoint
// Endpoint discovery :ref:`architecture overview <arch_overview_service_discovery_types_eds>`
service EndpointDiscoveryService {
option (envoy.annotations.resource).type = "envoy.api.v2.ClusterLoadAssignment";
// The resource_names field in DiscoveryRequest specifies a list of clusters
// to subscribe to updates for.
rpc StreamEndpoints(stream DiscoveryRequest) returns (stream DiscoveryResponse) {

@ -8,6 +8,7 @@ import "google/api/annotations.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/wrappers.proto";
import "envoy/annotations/resource.proto";
import "udpa/annotations/migrate.proto";
import "validate/validate.proto";
@ -27,6 +28,8 @@ option (udpa.annotations.file_migrate).move_to_package = "envoy.service.listener
// consist of a complete update of all listeners. Existing connections will be
// allowed to drain from listeners that are no longer present.
service ListenerDiscoveryService {
option (envoy.annotations.resource).type = "envoy.api.v2.Listener";
rpc DeltaListeners(stream DeltaDiscoveryRequest) returns (stream DeltaDiscoveryResponse) {
}

@ -7,6 +7,7 @@ import "envoy/api/v2/discovery.proto";
import "google/api/annotations.proto";
import "google/protobuf/wrappers.proto";
import "envoy/annotations/resource.proto";
import "udpa/annotations/migrate.proto";
import "validate/validate.proto";
@ -26,6 +27,8 @@ option (udpa.annotations.file_migrate).move_to_package = "envoy.service.route.v3
// configurations. Each listener will bind its HTTP connection manager filter to
// a route table via this identifier.
service RouteDiscoveryService {
option (envoy.annotations.resource).type = "envoy.api.v2.RouteConfiguration";
rpc StreamRoutes(stream DiscoveryRequest) returns (stream DiscoveryResponse) {
}
@ -49,6 +52,8 @@ service RouteDiscoveryService {
// contains a list of virtual host names that have been :ref:`unsubscribed
// <xds_protocol_unsubscribe>` from the routing table associated with the RouteConfiguration.
service VirtualHostDiscoveryService {
option (envoy.annotations.resource).type = "envoy.api.v2.route.VirtualHost";
rpc DeltaVirtualHosts(stream DeltaDiscoveryRequest) returns (stream DeltaDiscoveryResponse) {
}
}

@ -6,6 +6,7 @@ import "envoy/api/v2/discovery.proto";
import "google/api/annotations.proto";
import "envoy/annotations/resource.proto";
import "udpa/annotations/migrate.proto";
import public "envoy/api/v2/scoped_route.proto";
@ -27,6 +28,8 @@ option (udpa.annotations.file_migrate).move_to_package = "envoy.service.route.v3
// :ref:`RouteConfiguration<envoy_api_msg_RouteConfiguration>` message) to each
// HTTP request.
service ScopedRoutesDiscoveryService {
option (envoy.annotations.resource).type = "envoy.api.v2.ScopedRouteConfiguration";
rpc StreamScopedRoutes(stream DiscoveryRequest) returns (stream DiscoveryResponse) {
}

@ -7,6 +7,7 @@ licenses(["notice"]) # Apache 2
api_proto_package(
has_services = True,
deps = [
"//envoy/annotations:pkg",
"//envoy/api/v2:pkg",
"//envoy/service/discovery/v3alpha:pkg",
"@com_github_cncf_udpa//udpa/annotations:pkg",

@ -8,6 +8,8 @@ import "google/api/annotations.proto";
import "udpa/annotations/versioning.proto";
import "envoy/annotations/resource.proto";
option java_package = "io.envoyproxy.envoy.service.cluster.v3alpha";
option java_outer_classname = "CdsProto";
option java_multiple_files = true;
@ -17,6 +19,8 @@ option java_generic_services = true;
// Return list of all clusters this proxy will load balance to.
service ClusterDiscoveryService {
option (envoy.annotations.resource).type = "envoy.config.cluster.v3alpha.Cluster";
rpc StreamClusters(stream discovery.v3alpha.DiscoveryRequest)
returns (stream discovery.v3alpha.DiscoveryResponse) {
}

@ -7,6 +7,7 @@ licenses(["notice"]) # Apache 2
api_proto_package(
has_services = True,
deps = [
"//envoy/annotations:pkg",
"//envoy/api/v2:pkg",
"//envoy/api/v2/core:pkg",
"//envoy/api/v2/endpoint:pkg",

@ -7,6 +7,7 @@ import "envoy/api/v2/discovery.proto";
import "google/api/annotations.proto";
import "google/protobuf/struct.proto";
import "envoy/annotations/resource.proto";
import "udpa/annotations/migrate.proto";
import "validate/validate.proto";
@ -21,6 +22,8 @@ option (udpa.annotations.file_migrate).move_to_package = "envoy.service.runtime.
// Discovery service for Runtime resources.
service RuntimeDiscoveryService {
option (envoy.annotations.resource).type = "envoy.service.discovery.v2.Runtime";
rpc StreamRuntime(stream api.v2.DiscoveryRequest) returns (stream api.v2.DiscoveryResponse) {
}

@ -6,6 +6,7 @@ import "envoy/api/v2/discovery.proto";
import "google/api/annotations.proto";
import "envoy/annotations/resource.proto";
import "udpa/annotations/migrate.proto";
option java_package = "io.envoyproxy.envoy.service.discovery.v2";
@ -15,6 +16,8 @@ option java_generic_services = true;
option (udpa.annotations.file_migrate).move_to_package = "envoy.service.secret.v3alpha";
service SecretDiscoveryService {
option (envoy.annotations.resource).type = "envoy.api.v2.auth.Secret";
rpc DeltaSecrets(stream api.v2.DeltaDiscoveryRequest)
returns (stream api.v2.DeltaDiscoveryResponse) {
}

@ -7,6 +7,7 @@ licenses(["notice"]) # Apache 2
api_proto_package(
has_services = True,
deps = [
"//envoy/annotations:pkg",
"//envoy/api/v2:pkg",
"//envoy/service/discovery/v3alpha:pkg",
"@com_github_cncf_udpa//udpa/annotations:pkg",

@ -10,6 +10,7 @@ import "google/protobuf/wrappers.proto";
import "udpa/annotations/versioning.proto";
import "envoy/annotations/resource.proto";
import "validate/validate.proto";
option java_package = "io.envoyproxy.envoy.service.endpoint.v3alpha";
@ -21,6 +22,8 @@ option java_generic_services = true;
// Endpoint discovery :ref:`architecture overview <arch_overview_service_discovery_types_eds>`
service EndpointDiscoveryService {
option (envoy.annotations.resource).type = "envoy.config.endpoint.v3alpha.ClusterLoadAssignment";
// The resource_names field in DiscoveryRequest specifies a list of clusters
// to subscribe to updates for.
rpc StreamEndpoints(stream discovery.v3alpha.DiscoveryRequest)

@ -7,6 +7,7 @@ licenses(["notice"]) # Apache 2
api_proto_package(
has_services = True,
deps = [
"//envoy/annotations:pkg",
"//envoy/api/v2:pkg",
"//envoy/service/discovery/v3alpha:pkg",
"@com_github_cncf_udpa//udpa/annotations:pkg",

@ -10,6 +10,7 @@ import "google/protobuf/wrappers.proto";
import "udpa/annotations/versioning.proto";
import "envoy/annotations/resource.proto";
import "validate/validate.proto";
option java_package = "io.envoyproxy.envoy.service.listener.v3alpha";
@ -25,6 +26,8 @@ option java_generic_services = true;
// consist of a complete update of all listeners. Existing connections will be
// allowed to drain from listeners that are no longer present.
service ListenerDiscoveryService {
option (envoy.annotations.resource).type = "envoy.config.listener.v3alpha.Listener";
rpc DeltaListeners(stream discovery.v3alpha.DeltaDiscoveryRequest)
returns (stream discovery.v3alpha.DeltaDiscoveryResponse) {
}

@ -7,6 +7,7 @@ licenses(["notice"]) # Apache 2
api_proto_package(
has_services = True,
deps = [
"//envoy/annotations:pkg",
"//envoy/api/v2:pkg",
"//envoy/service/discovery/v3alpha:pkg",
"@com_github_cncf_udpa//udpa/annotations:pkg",

@ -9,6 +9,7 @@ import "google/protobuf/wrappers.proto";
import "udpa/annotations/versioning.proto";
import "envoy/annotations/resource.proto";
import "validate/validate.proto";
option java_package = "io.envoyproxy.envoy.service.route.v3alpha";
@ -24,6 +25,8 @@ option java_generic_services = true;
// configurations. Each listener will bind its HTTP connection manager filter to
// a route table via this identifier.
service RouteDiscoveryService {
option (envoy.annotations.resource).type = "envoy.config.route.v3alpha.RouteConfiguration";
rpc StreamRoutes(stream discovery.v3alpha.DiscoveryRequest)
returns (stream discovery.v3alpha.DiscoveryResponse) {
}
@ -52,6 +55,8 @@ service RouteDiscoveryService {
// :ref:`unsubscribed <xds_protocol_unsubscribe>` from the routing table associated with the
// RouteConfiguration.
service VirtualHostDiscoveryService {
option (envoy.annotations.resource).type = "envoy.config.route.v3alpha.VirtualHost";
rpc DeltaVirtualHosts(stream discovery.v3alpha.DeltaDiscoveryRequest)
returns (stream discovery.v3alpha.DeltaDiscoveryResponse) {
}

@ -8,6 +8,8 @@ import "google/api/annotations.proto";
import "udpa/annotations/versioning.proto";
import "envoy/annotations/resource.proto";
option java_package = "io.envoyproxy.envoy.service.route.v3alpha";
option java_outer_classname = "SrdsProto";
option java_multiple_files = true;
@ -24,6 +26,8 @@ option java_generic_services = true;
// :ref:`RouteConfiguration<envoy_api_msg_config.route.v3alpha.RouteConfiguration>` message) to each
// HTTP request.
service ScopedRoutesDiscoveryService {
option (envoy.annotations.resource).type = "envoy.config.route.v3alpha.ScopedRouteConfiguration";
rpc StreamScopedRoutes(stream discovery.v3alpha.DiscoveryRequest)
returns (stream discovery.v3alpha.DiscoveryResponse) {
}

@ -7,6 +7,7 @@ licenses(["notice"]) # Apache 2
api_proto_package(
has_services = True,
deps = [
"//envoy/annotations:pkg",
"//envoy/service/discovery/v2:pkg",
"//envoy/service/discovery/v3alpha:pkg",
"@com_github_cncf_udpa//udpa/annotations:pkg",

@ -9,6 +9,7 @@ import "google/protobuf/struct.proto";
import "udpa/annotations/versioning.proto";
import "envoy/annotations/resource.proto";
import "validate/validate.proto";
option java_package = "io.envoyproxy.envoy.service.runtime.v3alpha";
@ -21,6 +22,8 @@ option java_generic_services = true;
// Discovery service for Runtime resources.
service RuntimeDiscoveryService {
option (envoy.annotations.resource).type = "envoy.service.runtime.v3alpha.Runtime";
rpc StreamRuntime(stream discovery.v3alpha.DiscoveryRequest)
returns (stream discovery.v3alpha.DiscoveryResponse) {
}

@ -7,6 +7,7 @@ licenses(["notice"]) # Apache 2
api_proto_package(
has_services = True,
deps = [
"//envoy/annotations:pkg",
"//envoy/service/discovery/v2:pkg",
"//envoy/service/discovery/v3alpha:pkg",
"@com_github_cncf_udpa//udpa/annotations:pkg",

@ -8,12 +8,17 @@ import "google/api/annotations.proto";
import "udpa/annotations/versioning.proto";
import "envoy/annotations/resource.proto";
option java_package = "io.envoyproxy.envoy.service.secret.v3alpha";
option java_outer_classname = "SdsProto";
option java_multiple_files = true;
option java_generic_services = true;
service SecretDiscoveryService {
option (envoy.annotations.resource).type =
"envoy.extensions.transport_sockets.tls.v3alpha.Secret";
rpc DeltaSecrets(stream discovery.v3alpha.DeltaDiscoveryRequest)
returns (stream discovery.v3alpha.DeltaDiscoveryResponse) {
}

@ -6,25 +6,6 @@ api_cc_test(
name = "pgv_test",
srcs = ["pgv_test.cc"],
deps = [
"//envoy/api/v2:pkg_cc_proto",
"//envoy/api/v2/core:pkg_cc_proto",
"//envoy/config/bootstrap/v2:pkg_cc_proto",
"//envoy/config/filter/accesslog/v2:pkg_cc_proto",
"//envoy/config/filter/http/buffer/v2:pkg_cc_proto",
"//envoy/config/filter/http/fault/v2:pkg_cc_proto",
"//envoy/config/filter/http/gzip/v2:pkg_cc_proto",
"//envoy/config/filter/http/header_to_metadata/v2:pkg_cc_proto",
"//envoy/config/filter/http/health_check/v2:pkg_cc_proto",
"//envoy/config/filter/http/ip_tagging/v2:pkg_cc_proto",
"//envoy/config/filter/http/lua/v2:pkg_cc_proto",
"//envoy/config/filter/http/router/v2:pkg_cc_proto",
"//envoy/config/filter/http/squash/v2:pkg_cc_proto",
"//envoy/config/filter/http/transcoder/v2:pkg_cc_proto",
"//envoy/config/filter/network/http_connection_manager/v2:pkg_cc_proto",
"//envoy/config/filter/network/mongo_proxy/v2:pkg_cc_proto",
"//envoy/config/filter/network/redis_proxy/v2:pkg_cc_proto",
"//envoy/config/filter/network/tcp_proxy/v2:pkg_cc_proto",
"//envoy/config/health_checker/redis/v2:pkg_cc_proto",
"@envoy_api//envoy/api/v2:pkg_cc_proto",
"@envoy_api//envoy/api/v2/core:pkg_cc_proto",
"@envoy_api//envoy/api/v2/listener:pkg_cc_proto",

Loading…
Cancel
Save