github.com/polarismesh/polaris@v1.17.8/apiserver/xdsserverv3/lds.go (about)

     1  /**
     2   * Tencent is pleased to support the open source community by making Polaris available.
     3   *
     4   * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
     5   *
     6   * Licensed under the BSD 3-Clause License (the "License");
     7   * you may not use this file except in compliance with the License.
     8   * You may obtain a copy of the License at
     9   *
    10   * https://opensource.org/licenses/BSD-3-Clause
    11   *
    12   * Unless required by applicable law or agreed to in writing, software distributed
    13   * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
    14   * CONDITIONS OF ANY KIND, either express or implied. See the License for the
    15   * specific language governing permissions and limitations under the License.
    16   */
    17  
    18  package xdsserverv3
    19  
    20  import (
    21  	"fmt"
    22  
    23  	core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
    24  	corev3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
    25  	listenerv3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
    26  	httpinspector "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/listener/http_inspector/v3"
    27  	original_dstv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/listener/original_dst/v3"
    28  	tlsinspector "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/listener/tls_inspector/v3"
    29  	hcm "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3"
    30  	tlstrans "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3"
    31  	"github.com/envoyproxy/go-control-plane/pkg/cache/types"
    32  	"github.com/envoyproxy/go-control-plane/pkg/wellknown"
    33  	"github.com/golang/protobuf/ptypes/wrappers"
    34  
    35  	"github.com/polarismesh/polaris/apiserver/xdsserverv3/resource"
    36  	"github.com/polarismesh/polaris/common/model"
    37  	"github.com/polarismesh/polaris/service"
    38  )
    39  
    40  var (
    41  	tlsFilters = []*listenerv3.ListenerFilter{
    42  		{
    43  			Name: "envoy.filters.listener.http_inspector",
    44  			ConfigType: &listenerv3.ListenerFilter_TypedConfig{
    45  				TypedConfig: resource.MustNewAny(&httpinspector.HttpInspector{}),
    46  			},
    47  		},
    48  		{
    49  			Name: "envoy.filters.listener.tls_inspector",
    50  			ConfigType: &listenerv3.ListenerFilter_TypedConfig{
    51  				TypedConfig: resource.MustNewAny(&tlsinspector.TlsInspector{}),
    52  			},
    53  		},
    54  	}
    55  
    56  	defaultListenerFilters = []*listenerv3.ListenerFilter{
    57  		{
    58  			// type.googleapis.com/envoy.extensions.filters.listener.original_dst.v3.OriginalDst
    59  			Name: wellknown.OriginalDestination,
    60  			ConfigType: &listenerv3.ListenerFilter_TypedConfig{
    61  				TypedConfig: resource.MustNewAny(&original_dstv3.OriginalDst{}),
    62  			},
    63  		},
    64  	}
    65  
    66  	boundBindPort = map[corev3.TrafficDirection]uint32{
    67  		// envoy -> sidecar 方向 envoy 的监听端口,主要是 EnvoyGateway 以及 Sidecar InBound 场景
    68  		core.TrafficDirection_INBOUND: 15006,
    69  		// sidecar -> envoy 方向 envoy 的监听端口
    70  		core.TrafficDirection_OUTBOUND: 15001,
    71  	}
    72  )
    73  
    74  // LDSBuilder .
    75  type LDSBuilder struct {
    76  	client *resource.XDSClient
    77  	svr    service.DiscoverServer
    78  }
    79  
    80  func (lds *LDSBuilder) Init(clien *resource.XDSClient, svr service.DiscoverServer) {
    81  	lds.client = clien
    82  	lds.svr = svr
    83  }
    84  
    85  func (lds *LDSBuilder) Generate(option *resource.BuildOption) (interface{}, error) {
    86  	var resources []types.Resource
    87  
    88  	switch lds.client.RunType {
    89  	case resource.RunTypeGateway:
    90  		ret, err := lds.makeListener(option, core.TrafficDirection_OUTBOUND)
    91  		if err != nil {
    92  			return nil, err
    93  		}
    94  		resources = ret
    95  	case resource.RunTypeSidecar:
    96  		inBoundListener, err := lds.makeListener(option, corev3.TrafficDirection_INBOUND)
    97  		if err != nil {
    98  			return nil, err
    99  		}
   100  		outBoundListener, err := lds.makeListener(option, corev3.TrafficDirection_OUTBOUND)
   101  		if err != nil {
   102  			return nil, err
   103  		}
   104  		resources = append(resources, inBoundListener...)
   105  		resources = append(resources, outBoundListener...)
   106  	}
   107  	return resources, nil
   108  }
   109  
   110  func (lds *LDSBuilder) makeListener(option *resource.BuildOption,
   111  	direction corev3.TrafficDirection) ([]types.Resource, error) {
   112  
   113  	var boundHCM *hcm.HttpConnectionManager
   114  	if lds.client.IsGateway() {
   115  		boundHCM = resource.MakeGatewayBoundHCM()
   116  	} else {
   117  		selfService := model.ServiceKey{
   118  			Namespace: lds.client.GetSelfNamespace(),
   119  			Name:      lds.client.GetSelfService(),
   120  		}
   121  		boundHCM = resource.MakeSidecarBoundHCM(selfService, direction)
   122  	}
   123  
   124  	listener := makeDefaultListener(direction, boundHCM)
   125  	listener.ListenerFilters = append(listener.ListenerFilters, defaultListenerFilters...)
   126  
   127  	if option.TLSMode != resource.TLSModeNone {
   128  		listener.FilterChains = []*listenerv3.FilterChain{
   129  			{
   130  				FilterChainMatch: &listenerv3.FilterChainMatch{
   131  					TransportProtocol: "tls",
   132  				},
   133  				TransportSocket: resource.MakeTLSTransportSocket(&tlstrans.DownstreamTlsContext{
   134  					CommonTlsContext: resource.InboundCommonTLSContext,
   135  					RequireClientCertificate: &wrappers.BoolValue{
   136  						Value: true,
   137  					},
   138  				}),
   139  				Filters: []*listenerv3.Filter{
   140  					{
   141  						Name: "envoy.filters.network.http_connection_manager",
   142  						ConfigType: &listenerv3.Filter_TypedConfig{
   143  							TypedConfig: resource.MustNewAny(boundHCM),
   144  						},
   145  					}},
   146  				Name: "PassthroughFilterChain-TLS",
   147  			},
   148  		}
   149  
   150  		listener.ListenerFilters = append(tlsFilters, listener.ListenerFilters...)
   151  		if option.TLSMode == resource.TLSModeStrict {
   152  			listener.DefaultFilterChain = nil
   153  		}
   154  	}
   155  
   156  	return []types.Resource{
   157  		listener,
   158  	}, nil
   159  }
   160  
   161  func makeDefaultListener(trafficDirection corev3.TrafficDirection,
   162  	boundHCM *hcm.HttpConnectionManager) *listenerv3.Listener {
   163  
   164  	bindPort := boundBindPort[trafficDirection]
   165  	trafficDirectionName := corev3.TrafficDirection_name[int32(trafficDirection)]
   166  	listener := &listenerv3.Listener{
   167  		Name:             fmt.Sprintf("%s_%d", trafficDirectionName, bindPort),
   168  		TrafficDirection: trafficDirection,
   169  		Address: &core.Address{
   170  			Address: &core.Address_SocketAddress{
   171  				SocketAddress: &core.SocketAddress{
   172  					Protocol: core.SocketAddress_TCP,
   173  					Address:  "0.0.0.0",
   174  					PortSpecifier: &core.SocketAddress_PortValue{
   175  						PortValue: bindPort,
   176  					},
   177  				},
   178  			},
   179  		},
   180  		FilterChains: []*listenerv3.FilterChain{
   181  			{
   182  				Filters: []*listenerv3.Filter{
   183  					{
   184  						Name: wellknown.HTTPConnectionManager,
   185  						ConfigType: &listenerv3.Filter_TypedConfig{
   186  							TypedConfig: resource.MustNewAny(boundHCM),
   187  						},
   188  					},
   189  				},
   190  			},
   191  		},
   192  		DefaultFilterChain: resource.MakeDefaultFilterChain(),
   193  		ListenerFilters:    []*listenerv3.ListenerFilter{},
   194  	}
   195  	return listener
   196  }