func()

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,
	})
}