in grpc-xds/control-plane-go/pkg/xds/snapshot_builder.go [166:236]
func (b *SnapshotBuilder) Build() (cachev3.ResourceSnapshot, error) {
for address := range b.grpcServerListenerAddresses {
serverListener, err := lds.CreateGRPCServerListener(address.Host, address.Port, b.features.EnableDataPlaneTLS, b.features.RequireDataPlaneClientCerts, b.features.EnableRBAC)
if err != nil {
return nil, fmt.Errorf("could not create LDS server Listener for address %s:%d: %w", address.Host, address.Port, err)
}
b.listeners[serverListener.Name] = serverListener
}
if len(b.grpcServerListenerAddresses) > 0 {
routeConfigurationForGRPCServerListener, err := rds.CreateRouteConfigurationForGRPCServerListener(b.features.EnableRBAC)
if err != nil {
return nil, fmt.Errorf("could not create RDS RouteConfiguration for LDS server Listener: %w", err)
}
b.routeConfigurations[routeConfigurationForGRPCServerListener.Name] = routeConfigurationForGRPCServerListener
}
// Envoy proxies will not accept the gRPC server Listeners, because all the routes in their RouteConfigurations
// specify `NonForwardingAction` as the action.
// Envoy proxies will also not accept the API Listeners created for gRPC clients, because Envoy proxies can only
// have at most one API Listener defined, and that API Listener must be a static resource (not fetched via xDS).
// TODO: Add gRPC-JSON transcoding and gRPC HTTP/1.1 bridge.
// https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/grpc_json_transcoder_filter
// https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/grpc_http1_bridge_filter
envoyGRPCListener, err := lds.CreateEnvoyGRPCListener(50051, true)
if err != nil {
return nil, fmt.Errorf("could not create LDS Listener for Envoy proxy receiving gRPC requests: %w", err)
}
b.listeners[envoyGRPCListener.Name] = envoyGRPCListener
var clusterNames []string
for clusterName := range b.clusters {
clusterNames = append(clusterNames, clusterName)
}
routeConfigurationForEnvoyGRPCListener, err := rds.CreateRouteConfigurationForEnvoyGRPCListener(clusterNames)
if err != nil {
return nil, fmt.Errorf("could not create RDS RouteConfiguration for Envoy proxy gRPC LDS Listener: %w", err)
}
b.routeConfigurations[routeConfigurationForEnvoyGRPCListener.Name] = routeConfigurationForEnvoyGRPCListener
listenerResources := make([]types.Resource, len(b.listeners))
i := 0
for _, listener := range b.listeners {
listenerResources[i] = listener
i++
}
routeConfigurationResources := make([]types.Resource, len(b.routeConfigurations))
j := 0
for _, routeConfiguration := range b.routeConfigurations {
routeConfigurationResources[j] = routeConfiguration
j++
}
clusterResources := make([]types.Resource, len(b.clusters))
k := 0
for _, cluster := range b.clusters {
clusterResources[k] = cluster
k++
}
clusterLoadAssignmentResources := make([]types.Resource, len(b.clusterLoadAssignments))
l := 0
for _, clusterLoadAssignment := range b.clusterLoadAssignments {
clusterLoadAssignmentResources[l] = clusterLoadAssignment
l++
}
version := strconv.FormatInt(time.Now().UnixNano(), 10)
return cachev3.NewSnapshot(version, map[resource.Type][]types.Resource{
resource.ListenerType: listenerResources,
resource.RouteType: routeConfigurationResources,
resource.ClusterType: clusterResources,
resource.EndpointType: clusterLoadAssignmentResources,
})
}