Skip to content

Commit 950d462

Browse files
committed
added vhds support
1 parent 9d810c7 commit 950d462

File tree

12 files changed

+138
-45
lines changed

12 files changed

+138
-45
lines changed

api/src/main/proto/envoy/config/route/v3/route.proto

+6-6
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,12 @@ message RouteConfiguration {
3636
// An array of virtual hosts that make up the route table.
3737
repeated VirtualHost virtual_hosts = 2;
3838

39-
// An array of virtual hosts will be dynamically loaded via the VHDS API.
40-
// Both *virtual_hosts* and *vhds* fields will be used when present. *virtual_hosts* can be used
41-
// for a base routing table or for infrequently changing virtual hosts. *vhds* is used for
42-
// on-demand discovery of virtual hosts. The contents of these two fields will be merged to
43-
// generate a routing table for a given RouteConfiguration, with *vhds* derived configuration
44-
// taking precedence.
39+
// An array of virtual hosts will be dynamically loaded via the VHDS API.
40+
// Both *virtual_hosts* and *vhds* fields will be used when present. *virtual_hosts* can be used
41+
// for a base routing table or for infrequently changing virtual hosts. *vhds* is used for
42+
// on-demand discovery of virtual hosts. The contents of these two fields will be merged to
43+
// generate a routing table for a given RouteConfiguration, with *vhds* derived configuration
44+
// taking precedence.
4545
Vhds vhds = 9;
4646

4747
// Optionally specifies a list of HTTP headers that the connection manager

cache/src/main/java/io/envoyproxy/controlplane/cache/Resources.java

+13-6
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@
22

33
import static com.google.common.base.Strings.isNullOrEmpty;
44
import static io.envoyproxy.controlplane.cache.Resources.ApiVersion.V3;
5-
import static io.envoyproxy.controlplane.cache.Resources.ResourceType.CLUSTER;
6-
import static io.envoyproxy.controlplane.cache.Resources.ResourceType.ENDPOINT;
7-
import static io.envoyproxy.controlplane.cache.Resources.ResourceType.LISTENER;
8-
import static io.envoyproxy.controlplane.cache.Resources.ResourceType.ROUTE;
9-
import static io.envoyproxy.controlplane.cache.Resources.ResourceType.SECRET;
5+
import static io.envoyproxy.controlplane.cache.Resources.ResourceType.*;
106

117
import com.google.common.base.Preconditions;
128
import com.google.common.collect.ImmutableList;
@@ -21,6 +17,7 @@
2117
import io.envoyproxy.envoy.config.listener.v3.FilterChain;
2218
import io.envoyproxy.envoy.config.listener.v3.Listener;
2319
import io.envoyproxy.envoy.config.route.v3.RouteConfiguration;
20+
import io.envoyproxy.envoy.config.route.v3.VirtualHost;
2421
import io.envoyproxy.envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager;
2522
import io.envoyproxy.envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.RouteSpecifierCase;
2623
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.Secret;
@@ -42,6 +39,7 @@ public enum ResourceType {
4239
ENDPOINT,
4340
LISTENER,
4441
ROUTE,
42+
VIRTUAL_HOST,
4543
SECRET
4644
}
4745

@@ -64,6 +62,8 @@ public static class V3 {
6462
"type.googleapis.com/envoy.config.listener.v3" + ".Listener";
6563
public static final String ROUTE_TYPE_URL =
6664
"type.googleapis.com/envoy.config.route.v3" + ".RouteConfiguration";
65+
public static final String VIRTUAL_HOST_TYPE_URL =
66+
"type.googleapis.com/envoy.config.route.v3" + ".VirtualHost";
6767
public static final String SECRET_TYPE_URL =
6868
"type.googleapis.com/envoy.extensions" + ".transport_sockets.tls.v3.Secret";
6969

@@ -73,18 +73,20 @@ public static class V3 {
7373
ENDPOINT_TYPE_URL,
7474
LISTENER_TYPE_URL,
7575
ROUTE_TYPE_URL,
76+
VIRTUAL_HOST_TYPE_URL,
7677
SECRET_TYPE_URL);
7778
}
7879

7980
public static final List<ResourceType> RESOURCE_TYPES_IN_ORDER =
80-
ImmutableList.of(CLUSTER, ENDPOINT, LISTENER, ROUTE, SECRET);
81+
ImmutableList.of(CLUSTER, ENDPOINT, LISTENER, ROUTE, VIRTUAL_HOST, SECRET);
8182

8283
public static final Map<String, ResourceType> TYPE_URLS_TO_RESOURCE_TYPE =
8384
new ImmutableMap.Builder<String, ResourceType>()
8485
.put(Resources.V3.CLUSTER_TYPE_URL, CLUSTER)
8586
.put(Resources.V3.ENDPOINT_TYPE_URL, ENDPOINT)
8687
.put(Resources.V3.LISTENER_TYPE_URL, LISTENER)
8788
.put(Resources.V3.ROUTE_TYPE_URL, ROUTE)
89+
.put(Resources.V3.VIRTUAL_HOST_TYPE_URL, VIRTUAL_HOST)
8890
.put(Resources.V3.SECRET_TYPE_URL, SECRET)
8991
.build();
9092

@@ -94,6 +96,7 @@ public static class V3 {
9496
.put(Resources.V3.ENDPOINT_TYPE_URL, ClusterLoadAssignment.class)
9597
.put(Resources.V3.LISTENER_TYPE_URL, Listener.class)
9698
.put(Resources.V3.ROUTE_TYPE_URL, RouteConfiguration.class)
99+
.put(Resources.V3.VIRTUAL_HOST_TYPE_URL, VirtualHost.class)
97100
.put(Resources.V3.SECRET_TYPE_URL, Secret.class)
98101
.build();
99102

@@ -119,6 +122,10 @@ public static String getResourceName(Message resource) {
119122
return ((RouteConfiguration) resource).getName();
120123
}
121124

125+
if (resource instanceof VirtualHost) {
126+
return ((VirtualHost) resource).getName();
127+
}
128+
122129
if (resource instanceof Secret) {
123130
return ((Secret) resource).getName();
124131
}

cache/src/main/java/io/envoyproxy/controlplane/cache/SnapshotResources.java

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import com.google.auto.value.AutoValue;
44
import com.google.protobuf.Message;
5+
import com.google.protobuf.MessageLiteOrBuilder;
6+
57
import java.util.List;
68
import java.util.Map;
79
import java.util.stream.Collector;

cache/src/main/java/io/envoyproxy/controlplane/cache/TestResources.java

+47-5
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,18 @@
2020
import io.envoyproxy.envoy.config.listener.v3.Filter;
2121
import io.envoyproxy.envoy.config.listener.v3.FilterChain;
2222
import io.envoyproxy.envoy.config.listener.v3.Listener;
23-
import io.envoyproxy.envoy.config.route.v3.Route;
24-
import io.envoyproxy.envoy.config.route.v3.RouteAction;
25-
import io.envoyproxy.envoy.config.route.v3.RouteConfiguration;
26-
import io.envoyproxy.envoy.config.route.v3.RouteMatch;
27-
import io.envoyproxy.envoy.config.route.v3.VirtualHost;
23+
import io.envoyproxy.envoy.config.route.v3.*;
24+
import io.envoyproxy.envoy.config.route.v3.VirtualHost.Builder;
2825
import io.envoyproxy.envoy.extensions.filters.http.router.v3.Router;
2926
import io.envoyproxy.envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager;
3027
import io.envoyproxy.envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.CodecType;
3128
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.Secret;
3229
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.TlsCertificate;
30+
import io.envoyproxy.envoy.service.route.v3.VirtualHostDiscoveryService;
31+
32+
import java.util.ArrayList;
33+
import java.util.Collections;
34+
import java.util.List;
3335

3436
/**
3537
* {@code TestResources} provides helper methods for generating resource messages for testing. It is
@@ -209,6 +211,36 @@ public static Listener createListener(
209211
.build();
210212
}
211213

214+
/**
215+
* Returns a new test v3 route.
216+
*
217+
* @param routeName name of the new route
218+
*/
219+
public static RouteConfiguration createVHDSRoute(String routeName) {
220+
221+
ApiVersion adsTransportVersion = ApiVersion.V3;
222+
223+
ConfigSource edsSource =
224+
ConfigSource.newBuilder()
225+
.setResourceApiVersion(ApiVersion.V3)
226+
.setApiConfigSource(
227+
ApiConfigSource.newBuilder()
228+
.setTransportApiVersion(adsTransportVersion)
229+
.setApiType(ApiConfigSource.ApiType.DELTA_GRPC)
230+
.addGrpcServices(
231+
GrpcService.newBuilder()
232+
.setEnvoyGrpc(
233+
GrpcService.EnvoyGrpc.newBuilder()
234+
.setClusterName(XDS_CLUSTER))))
235+
.build();
236+
237+
RouteConfiguration routeConfigurationbuilder = RouteConfiguration.newBuilder()
238+
.setVhds(Vhds.newBuilder().setConfigSource(edsSource).build())
239+
.setName(routeName).build();
240+
241+
return routeConfigurationbuilder;
242+
}
243+
212244
/**
213245
* Returns a new test v3 route.
214246
*
@@ -229,6 +261,16 @@ public static RouteConfiguration createRoute(String routeName, String clusterNam
229261
.build();
230262
}
231263

264+
public static VirtualHost createVirtualHost(String name, int index, String domains) {
265+
return VirtualHost.newBuilder()
266+
.setName("all")
267+
.addDomains("*")
268+
.addRoutes(
269+
Route.newBuilder()
270+
.setMatch(RouteMatch.newBuilder().setPrefix("/")))
271+
.build();
272+
}
273+
232274
/**
233275
* Returns a new test v3 secret.
234276
*

cache/src/main/java/io/envoyproxy/controlplane/cache/v3/Snapshot.java

+19-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.List;
2121
import java.util.Map;
2222
import java.util.Set;
23+
import io.envoyproxy.envoy.config.route.v3.VirtualHost;
2324

2425
/**
2526
* {@code Snapshot} is a data class that contains an internally consistent snapshot of v3 xDS resources. Snapshots
@@ -43,7 +44,10 @@ public static Snapshot create(
4344
Iterable<ClusterLoadAssignment> endpoints,
4445
Iterable<Listener> listeners,
4546
Iterable<RouteConfiguration> routes,
47+
Iterable<VirtualHost> virtualHosts,
4648
Iterable<Secret> secrets,
49+
50+
4751
String version) {
4852

4953
return new AutoValue_Snapshot(
@@ -56,7 +60,9 @@ public static Snapshot create(
5660
SnapshotResources
5761
.create(generateSnapshotResourceIterable(routes), version),
5862
SnapshotResources
59-
.create(generateSnapshotResourceIterable(secrets), version));
63+
.create(generateSnapshotResourceIterable(secrets), version),
64+
SnapshotResources
65+
.create(generateSnapshotResourceIterable(virtualHosts), version));
6066
}
6167

6268
/**
@@ -81,6 +87,8 @@ public static Snapshot create(
8187
String listenersVersion,
8288
Iterable<RouteConfiguration> routes,
8389
String routesVersion,
90+
Iterable<VirtualHost> virtualHosts,
91+
String virtualHostsVersion,
8492
Iterable<Secret> secrets,
8593
String secretsVersion) {
8694

@@ -94,6 +102,8 @@ public static Snapshot create(
94102
listenersVersion),
95103
SnapshotResources
96104
.create(generateSnapshotResourceIterable(routes), routesVersion),
105+
SnapshotResources
106+
.create(generateSnapshotResourceIterable(virtualHosts), virtualHostsVersion),
97107
SnapshotResources.create(generateSnapshotResourceIterable(secrets),
98108
secretsVersion));
99109
}
@@ -105,7 +115,7 @@ public static Snapshot create(
105115
*/
106116
public static Snapshot createEmpty(String version) {
107117
return create(Collections.emptySet(), Collections.emptySet(),
108-
Collections.emptySet(), Collections.emptySet(), Collections.emptySet(), version);
118+
Collections.emptySet(), Collections.emptySet(), Collections.emptySet(), Collections.emptySet(), version);
109119
}
110120

111121
/**
@@ -132,6 +142,7 @@ public static Snapshot createEmpty(String version) {
132142
* Returns all secret items in the SDS payload.
133143
*/
134144
public abstract SnapshotResources<Secret> secrets();
145+
public abstract SnapshotResources<VirtualHost> virtualHosts();
135146

136147
/**
137148
* Asserts that all dependent resources are included in the snapshot. All EDS resources are listed by name in CDS
@@ -189,6 +200,8 @@ public Map<String, VersionedResource<?>> resources(String typeUrl) {
189200
return (Map) listeners().resources();
190201
case ROUTE:
191202
return (Map) routes().resources();
203+
case VIRTUAL_HOST:
204+
return (Map) virtualHosts().resources();
192205
case SECRET:
193206
return (Map) secrets().resources();
194207
default:
@@ -211,6 +224,8 @@ public Map<String, VersionedResource<?>> versionedResources(ResourceType resourc
211224
return (Map) listeners().versionedResources();
212225
case ROUTE:
213226
return (Map) routes().versionedResources();
227+
case VIRTUAL_HOST:
228+
return (Map) virtualHosts().versionedResources();
214229
case SECRET:
215230
return (Map) secrets().versionedResources();
216231
default:
@@ -266,6 +281,8 @@ public String version(ResourceType resourceType, List<String> resourceNames) {
266281
return listeners().version(resourceNames);
267282
case ROUTE:
268283
return routes().version(resourceNames);
284+
case VIRTUAL_HOST:
285+
return virtualHosts().version(resourceNames);
269286
case SECRET:
270287
return secrets().version(resourceNames);
271288
default:

cache/src/test/java/io/envoyproxy/controlplane/cache/v3/SimpleCacheTest.java

+8-8
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,7 @@
77
import com.google.common.collect.ImmutableList;
88
import com.google.common.collect.Sets;
99
import com.google.protobuf.Message;
10-
import io.envoyproxy.controlplane.cache.NodeGroup;
11-
import io.envoyproxy.controlplane.cache.Resources;
12-
import io.envoyproxy.controlplane.cache.Response;
13-
import io.envoyproxy.controlplane.cache.StatusInfo;
14-
import io.envoyproxy.controlplane.cache.VersionedResource;
15-
import io.envoyproxy.controlplane.cache.Watch;
16-
import io.envoyproxy.controlplane.cache.XdsRequest;
10+
import io.envoyproxy.controlplane.cache.*;
1711
import io.envoyproxy.envoy.config.cluster.v3.Cluster;
1812
import io.envoyproxy.envoy.config.core.v3.Node;
1913
import io.envoyproxy.envoy.config.endpoint.v3.ClusterLoadAssignment;
@@ -49,14 +43,18 @@ public class SimpleCacheTest {
4943
ImmutableList.of(ClusterLoadAssignment.getDefaultInstance()),
5044
ImmutableList.of(Listener.newBuilder().setName(LISTENER_NAME).build()),
5145
ImmutableList.of(RouteConfiguration.newBuilder().setName(ROUTE_NAME).build()),
46+
ImmutableList.of(TestResources.createVirtualHost("v1", 1, "a")),
5247
ImmutableList.of(Secret.newBuilder().setName(SECRET_NAME).build()),
48+
5349
VERSION1);
5450

5551
private static final Snapshot SNAPSHOT2 = Snapshot.create(
5652
ImmutableList.of(Cluster.newBuilder().setName(CLUSTER_NAME).build()),
5753
ImmutableList.of(ClusterLoadAssignment.getDefaultInstance()),
5854
ImmutableList.of(Listener.newBuilder().setName(LISTENER_NAME).build()),
5955
ImmutableList.of(RouteConfiguration.newBuilder().setName(ROUTE_NAME).build()),
56+
ImmutableList.of(TestResources.createVirtualHost("v1", 1, "a")),
57+
6058
ImmutableList.of(Secret.newBuilder().setName(SECRET_NAME).build()),
6159
VERSION2);
6260

@@ -67,6 +65,8 @@ public class SimpleCacheTest {
6765
ClusterLoadAssignment.newBuilder().setClusterName(SECONDARY_CLUSTER_NAME).build()),
6866
ImmutableList.of(Listener.newBuilder().setName(LISTENER_NAME).build()),
6967
ImmutableList.of(RouteConfiguration.newBuilder().setName(ROUTE_NAME).build()),
68+
ImmutableList.of(TestResources.createVirtualHost("v1", 1, "a")),
69+
7070
ImmutableList.of(Secret.newBuilder().setName(SECRET_NAME).build()),
7171
VERSION2);
7272

@@ -429,7 +429,7 @@ public void watchesAreReleasedAfterCancel() {
429429
public void watchIsLeftOpenIfNotRespondedImmediately() {
430430
SimpleCache<String> cache = new SimpleCache<>(new SingleNodeGroup());
431431
cache.setSnapshot(SingleNodeGroup.GROUP, Snapshot.create(
432-
ImmutableList.of(), ImmutableList.of(), ImmutableList.of(), ImmutableList.of(), ImmutableList.of(), VERSION1));
432+
ImmutableList.of(), ImmutableList.of(), ImmutableList.of(), ImmutableList.of(), ImmutableList.of(), ImmutableList.of(),VERSION1));
433433

434434
ResponseTracker responseTracker = new ResponseTracker();
435435
Watch watch = cache.createWatch(

0 commit comments

Comments
 (0)