package controlplane import ( "context" "encoding/hex" "fmt" envoy_service_discovery_v3 "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" "golang.org/x/sync/errgroup" "github.com/pomerium/pomerium/internal/log" "github.com/pomerium/pomerium/internal/telemetry/trace" "github.com/pomerium/pomerium/pkg/cryptutil" "github.com/pomerium/pomerium/pkg/protoutil" ) const ( clusterTypeURL = "type.googleapis.com/envoy.config.cluster.v3.Cluster" listenerTypeURL = "type.googleapis.com/envoy.config.listener.v3.Listener" routeConfigurationTypeURL = "type.googleapis.com/envoy.config.route.v3.RouteConfiguration" ) func (srv *Server) buildDiscoveryResources(ctx context.Context) (map[string][]*envoy_service_discovery_v3.Resource, error) { ctx, span := trace.StartSpan(ctx, "controlplane.Server.buildDiscoveryResources") defer span.End() cfg := srv.currentConfig.Load() log.Info(ctx).Msg("controlplane: building discovery resources") eg, ctx := errgroup.WithContext(ctx) var clusterResources []*envoy_service_discovery_v3.Resource eg.Go(func() error { clusters, err := srv.Builder.BuildClusters(ctx, cfg) if err != nil { return fmt.Errorf("error building clusters: %w", err) } for _, cluster := range clusters { clusterResources = append(clusterResources, &envoy_service_discovery_v3.Resource{ Name: cluster.Name, Version: hex.EncodeToString(cryptutil.HashProto(cluster)), Resource: protoutil.NewAny(cluster), }) } return nil }) var listenerResources []*envoy_service_discovery_v3.Resource eg.Go(func() error { listeners, err := srv.Builder.BuildListeners(ctx, cfg, false) if err != nil { return fmt.Errorf("error building listeners: %w", err) } for _, listener := range listeners { listenerResources = append(listenerResources, &envoy_service_discovery_v3.Resource{ Name: listener.Name, Version: hex.EncodeToString(cryptutil.HashProto(listener)), Resource: protoutil.NewAny(listener), }) } return nil }) var routeConfigurationResources []*envoy_service_discovery_v3.Resource eg.Go(func() error { routeConfigurations, err := srv.Builder.BuildRouteConfigurations(ctx, cfg) if err != nil { return fmt.Errorf("error building route configurations: %w", err) } for _, routeConfiguration := range routeConfigurations { routeConfigurationResources = append(routeConfigurationResources, &envoy_service_discovery_v3.Resource{ Name: routeConfiguration.Name, Version: hex.EncodeToString(cryptutil.HashProto(routeConfiguration)), Resource: protoutil.NewAny(routeConfiguration), }) } return nil }) err := eg.Wait() if err != nil { return nil, err } log.Info(ctx). Int("cluster-count", len(clusterResources)). Int("listener-count", len(listenerResources)). Int("route-configuration-count", len(routeConfigurationResources)). Msg("controlplane: built discovery resources") return map[string][]*envoy_service_discovery_v3.Resource{ clusterTypeURL: clusterResources, listenerTypeURL: listenerResources, routeConfigurationTypeURL: routeConfigurationResources, }, nil }