Skip to content

Commit

Permalink
added vhds support
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-deb committed Nov 24, 2022
1 parent 9d810c7 commit 950d462
Show file tree
Hide file tree
Showing 12 changed files with 138 additions and 45 deletions.
12 changes: 6 additions & 6 deletions api/src/main/proto/envoy/config/route/v3/route.proto
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ message RouteConfiguration {
// An array of virtual hosts that make up the route table.
repeated VirtualHost virtual_hosts = 2;

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

// Optionally specifies a list of HTTP headers that the connection manager
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@

import static com.google.common.base.Strings.isNullOrEmpty;
import static io.envoyproxy.controlplane.cache.Resources.ApiVersion.V3;
import static io.envoyproxy.controlplane.cache.Resources.ResourceType.CLUSTER;
import static io.envoyproxy.controlplane.cache.Resources.ResourceType.ENDPOINT;
import static io.envoyproxy.controlplane.cache.Resources.ResourceType.LISTENER;
import static io.envoyproxy.controlplane.cache.Resources.ResourceType.ROUTE;
import static io.envoyproxy.controlplane.cache.Resources.ResourceType.SECRET;
import static io.envoyproxy.controlplane.cache.Resources.ResourceType.*;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
Expand All @@ -21,6 +17,7 @@
import io.envoyproxy.envoy.config.listener.v3.FilterChain;
import io.envoyproxy.envoy.config.listener.v3.Listener;
import io.envoyproxy.envoy.config.route.v3.RouteConfiguration;
import io.envoyproxy.envoy.config.route.v3.VirtualHost;
import io.envoyproxy.envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager;
import io.envoyproxy.envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.RouteSpecifierCase;
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.Secret;
Expand All @@ -42,6 +39,7 @@ public enum ResourceType {
ENDPOINT,
LISTENER,
ROUTE,
VIRTUAL_HOST,
SECRET
}

Expand All @@ -64,6 +62,8 @@ public static class V3 {
"type.googleapis.com/envoy.config.listener.v3" + ".Listener";
public static final String ROUTE_TYPE_URL =
"type.googleapis.com/envoy.config.route.v3" + ".RouteConfiguration";
public static final String VIRTUAL_HOST_TYPE_URL =
"type.googleapis.com/envoy.config.route.v3" + ".VirtualHost";
public static final String SECRET_TYPE_URL =
"type.googleapis.com/envoy.extensions" + ".transport_sockets.tls.v3.Secret";

Expand All @@ -73,18 +73,20 @@ public static class V3 {
ENDPOINT_TYPE_URL,
LISTENER_TYPE_URL,
ROUTE_TYPE_URL,
VIRTUAL_HOST_TYPE_URL,
SECRET_TYPE_URL);
}

public static final List<ResourceType> RESOURCE_TYPES_IN_ORDER =
ImmutableList.of(CLUSTER, ENDPOINT, LISTENER, ROUTE, SECRET);
ImmutableList.of(CLUSTER, ENDPOINT, LISTENER, ROUTE, VIRTUAL_HOST, SECRET);

public static final Map<String, ResourceType> TYPE_URLS_TO_RESOURCE_TYPE =
new ImmutableMap.Builder<String, ResourceType>()
.put(Resources.V3.CLUSTER_TYPE_URL, CLUSTER)
.put(Resources.V3.ENDPOINT_TYPE_URL, ENDPOINT)
.put(Resources.V3.LISTENER_TYPE_URL, LISTENER)
.put(Resources.V3.ROUTE_TYPE_URL, ROUTE)
.put(Resources.V3.VIRTUAL_HOST_TYPE_URL, VIRTUAL_HOST)
.put(Resources.V3.SECRET_TYPE_URL, SECRET)
.build();

Expand All @@ -94,6 +96,7 @@ public static class V3 {
.put(Resources.V3.ENDPOINT_TYPE_URL, ClusterLoadAssignment.class)
.put(Resources.V3.LISTENER_TYPE_URL, Listener.class)
.put(Resources.V3.ROUTE_TYPE_URL, RouteConfiguration.class)
.put(Resources.V3.VIRTUAL_HOST_TYPE_URL, VirtualHost.class)
.put(Resources.V3.SECRET_TYPE_URL, Secret.class)
.build();

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

if (resource instanceof VirtualHost) {
return ((VirtualHost) resource).getName();
}

if (resource instanceof Secret) {
return ((Secret) resource).getName();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import com.google.auto.value.AutoValue;
import com.google.protobuf.Message;
import com.google.protobuf.MessageLiteOrBuilder;

import java.util.List;
import java.util.Map;
import java.util.stream.Collector;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,18 @@
import io.envoyproxy.envoy.config.listener.v3.Filter;
import io.envoyproxy.envoy.config.listener.v3.FilterChain;
import io.envoyproxy.envoy.config.listener.v3.Listener;
import io.envoyproxy.envoy.config.route.v3.Route;
import io.envoyproxy.envoy.config.route.v3.RouteAction;
import io.envoyproxy.envoy.config.route.v3.RouteConfiguration;
import io.envoyproxy.envoy.config.route.v3.RouteMatch;
import io.envoyproxy.envoy.config.route.v3.VirtualHost;
import io.envoyproxy.envoy.config.route.v3.*;
import io.envoyproxy.envoy.config.route.v3.VirtualHost.Builder;
import io.envoyproxy.envoy.extensions.filters.http.router.v3.Router;
import io.envoyproxy.envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager;
import io.envoyproxy.envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.CodecType;
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.Secret;
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.TlsCertificate;
import io.envoyproxy.envoy.service.route.v3.VirtualHostDiscoveryService;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

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

/**
* Returns a new test v3 route.
*
* @param routeName name of the new route
*/
public static RouteConfiguration createVHDSRoute(String routeName) {

ApiVersion adsTransportVersion = ApiVersion.V3;

ConfigSource edsSource =
ConfigSource.newBuilder()
.setResourceApiVersion(ApiVersion.V3)
.setApiConfigSource(
ApiConfigSource.newBuilder()
.setTransportApiVersion(adsTransportVersion)
.setApiType(ApiConfigSource.ApiType.DELTA_GRPC)
.addGrpcServices(
GrpcService.newBuilder()
.setEnvoyGrpc(
GrpcService.EnvoyGrpc.newBuilder()
.setClusterName(XDS_CLUSTER))))
.build();

RouteConfiguration routeConfigurationbuilder = RouteConfiguration.newBuilder()
.setVhds(Vhds.newBuilder().setConfigSource(edsSource).build())
.setName(routeName).build();

return routeConfigurationbuilder;
}

/**
* Returns a new test v3 route.
*
Expand All @@ -229,6 +261,16 @@ public static RouteConfiguration createRoute(String routeName, String clusterNam
.build();
}

public static VirtualHost createVirtualHost(String name, int index, String domains) {
return VirtualHost.newBuilder()
.setName("all")
.addDomains("*")
.addRoutes(
Route.newBuilder()
.setMatch(RouteMatch.newBuilder().setPrefix("/")))
.build();
}

/**
* Returns a new test v3 secret.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import io.envoyproxy.envoy.config.route.v3.VirtualHost;

/**
* {@code Snapshot} is a data class that contains an internally consistent snapshot of v3 xDS resources. Snapshots
Expand All @@ -43,7 +44,10 @@ public static Snapshot create(
Iterable<ClusterLoadAssignment> endpoints,
Iterable<Listener> listeners,
Iterable<RouteConfiguration> routes,
Iterable<VirtualHost> virtualHosts,
Iterable<Secret> secrets,


String version) {

return new AutoValue_Snapshot(
Expand All @@ -56,7 +60,9 @@ public static Snapshot create(
SnapshotResources
.create(generateSnapshotResourceIterable(routes), version),
SnapshotResources
.create(generateSnapshotResourceIterable(secrets), version));
.create(generateSnapshotResourceIterable(secrets), version),
SnapshotResources
.create(generateSnapshotResourceIterable(virtualHosts), version));
}

/**
Expand All @@ -81,6 +87,8 @@ public static Snapshot create(
String listenersVersion,
Iterable<RouteConfiguration> routes,
String routesVersion,
Iterable<VirtualHost> virtualHosts,
String virtualHostsVersion,
Iterable<Secret> secrets,
String secretsVersion) {

Expand All @@ -94,6 +102,8 @@ public static Snapshot create(
listenersVersion),
SnapshotResources
.create(generateSnapshotResourceIterable(routes), routesVersion),
SnapshotResources
.create(generateSnapshotResourceIterable(virtualHosts), virtualHostsVersion),
SnapshotResources.create(generateSnapshotResourceIterable(secrets),
secretsVersion));
}
Expand All @@ -105,7 +115,7 @@ public static Snapshot create(
*/
public static Snapshot createEmpty(String version) {
return create(Collections.emptySet(), Collections.emptySet(),
Collections.emptySet(), Collections.emptySet(), Collections.emptySet(), version);
Collections.emptySet(), Collections.emptySet(), Collections.emptySet(), Collections.emptySet(), version);
}

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

/**
* Asserts that all dependent resources are included in the snapshot. All EDS resources are listed by name in CDS
Expand Down Expand Up @@ -189,6 +200,8 @@ public Map<String, VersionedResource<?>> resources(String typeUrl) {
return (Map) listeners().resources();
case ROUTE:
return (Map) routes().resources();
case VIRTUAL_HOST:
return (Map) virtualHosts().resources();
case SECRET:
return (Map) secrets().resources();
default:
Expand All @@ -211,6 +224,8 @@ public Map<String, VersionedResource<?>> versionedResources(ResourceType resourc
return (Map) listeners().versionedResources();
case ROUTE:
return (Map) routes().versionedResources();
case VIRTUAL_HOST:
return (Map) virtualHosts().versionedResources();
case SECRET:
return (Map) secrets().versionedResources();
default:
Expand Down Expand Up @@ -266,6 +281,8 @@ public String version(ResourceType resourceType, List<String> resourceNames) {
return listeners().version(resourceNames);
case ROUTE:
return routes().version(resourceNames);
case VIRTUAL_HOST:
return virtualHosts().version(resourceNames);
case SECRET:
return secrets().version(resourceNames);
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Sets;
import com.google.protobuf.Message;
import io.envoyproxy.controlplane.cache.NodeGroup;
import io.envoyproxy.controlplane.cache.Resources;
import io.envoyproxy.controlplane.cache.Response;
import io.envoyproxy.controlplane.cache.StatusInfo;
import io.envoyproxy.controlplane.cache.VersionedResource;
import io.envoyproxy.controlplane.cache.Watch;
import io.envoyproxy.controlplane.cache.XdsRequest;
import io.envoyproxy.controlplane.cache.*;
import io.envoyproxy.envoy.config.cluster.v3.Cluster;
import io.envoyproxy.envoy.config.core.v3.Node;
import io.envoyproxy.envoy.config.endpoint.v3.ClusterLoadAssignment;
Expand Down Expand Up @@ -49,14 +43,18 @@ public class SimpleCacheTest {
ImmutableList.of(ClusterLoadAssignment.getDefaultInstance()),
ImmutableList.of(Listener.newBuilder().setName(LISTENER_NAME).build()),
ImmutableList.of(RouteConfiguration.newBuilder().setName(ROUTE_NAME).build()),
ImmutableList.of(TestResources.createVirtualHost("v1", 1, "a")),
ImmutableList.of(Secret.newBuilder().setName(SECRET_NAME).build()),

VERSION1);

private static final Snapshot SNAPSHOT2 = Snapshot.create(
ImmutableList.of(Cluster.newBuilder().setName(CLUSTER_NAME).build()),
ImmutableList.of(ClusterLoadAssignment.getDefaultInstance()),
ImmutableList.of(Listener.newBuilder().setName(LISTENER_NAME).build()),
ImmutableList.of(RouteConfiguration.newBuilder().setName(ROUTE_NAME).build()),
ImmutableList.of(TestResources.createVirtualHost("v1", 1, "a")),

ImmutableList.of(Secret.newBuilder().setName(SECRET_NAME).build()),
VERSION2);

Expand All @@ -67,6 +65,8 @@ public class SimpleCacheTest {
ClusterLoadAssignment.newBuilder().setClusterName(SECONDARY_CLUSTER_NAME).build()),
ImmutableList.of(Listener.newBuilder().setName(LISTENER_NAME).build()),
ImmutableList.of(RouteConfiguration.newBuilder().setName(ROUTE_NAME).build()),
ImmutableList.of(TestResources.createVirtualHost("v1", 1, "a")),

ImmutableList.of(Secret.newBuilder().setName(SECRET_NAME).build()),
VERSION2);

Expand Down Expand Up @@ -429,7 +429,7 @@ public void watchesAreReleasedAfterCancel() {
public void watchIsLeftOpenIfNotRespondedImmediately() {
SimpleCache<String> cache = new SimpleCache<>(new SingleNodeGroup());
cache.setSnapshot(SingleNodeGroup.GROUP, Snapshot.create(
ImmutableList.of(), ImmutableList.of(), ImmutableList.of(), ImmutableList.of(), ImmutableList.of(), VERSION1));
ImmutableList.of(), ImmutableList.of(), ImmutableList.of(), ImmutableList.of(), ImmutableList.of(), ImmutableList.of(),VERSION1));

ResponseTracker responseTracker = new ResponseTracker();
Watch watch = cache.createWatch(
Expand Down
Loading

0 comments on commit 950d462

Please sign in to comment.