github.com/polarismesh/polaris@v1.17.8/apiserver/xdsserverv3/cds.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 "time" 23 24 cluster "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3" 25 core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" 26 corev3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" 27 rawbuffer "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/raw_buffer/v3" 28 tlstrans "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3" 29 "github.com/envoyproxy/go-control-plane/pkg/cache/types" 30 resourcev3 "github.com/envoyproxy/go-control-plane/pkg/resource/v3" 31 "github.com/envoyproxy/go-control-plane/pkg/wellknown" 32 "github.com/golang/protobuf/ptypes" 33 "google.golang.org/protobuf/types/known/structpb" 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 // CDSBuilder . 41 type CDSBuilder struct { 42 client *resource.XDSClient 43 svr service.DiscoverServer 44 } 45 46 func (cds *CDSBuilder) Init(client *resource.XDSClient, svr service.DiscoverServer) { 47 cds.client = client 48 cds.svr = svr 49 } 50 51 const ( 52 SniTemp = "outbound_.default_.%s.%s.svc.cluster.local" 53 ) 54 55 func (cds *CDSBuilder) Generate(option *resource.BuildOption) (interface{}, error) { 56 var clusters []types.Resource 57 58 // 默认 passthrough cluster 59 clusters = append(clusters, resource.PassthroughCluster) 60 61 inBoundClusters, err := cds.GenerateByDirection(option, corev3.TrafficDirection_INBOUND) 62 if err != nil { 63 return nil, err 64 } 65 outBoundClusters, err := cds.GenerateByDirection(option, corev3.TrafficDirection_OUTBOUND) 66 if err != nil { 67 return nil, err 68 } 69 70 clusters = append(clusters, inBoundClusters...) 71 clusters = append(clusters, outBoundClusters...) 72 return clusters, nil 73 } 74 75 func (cds *CDSBuilder) GenerateByDirection(option *resource.BuildOption, 76 direction corev3.TrafficDirection) ([]types.Resource, error) { 77 var clusters []types.Resource 78 79 selfServiceKey := model.ServiceKey{ 80 Namespace: cds.client.GetSelfNamespace(), 81 Name: cds.client.GetSelfService(), 82 } 83 84 ignore := func(svcKey model.ServiceKey) bool { 85 // 如果是 INBOUND 场景,只需要下发 XDS Sidecar Node 所归属的服务 INBOUND Cluster 规则 86 if direction == core.TrafficDirection_INBOUND { 87 if cds.client.IsGateway() { 88 return true 89 } 90 if !cds.client.IsGateway() && !selfServiceKey.Equal(&svcKey) { 91 return true 92 } 93 } 94 // 如果是网关,则自己的数据不会下发 95 if cds.client.IsGateway() && selfServiceKey.Equal(&svcKey) { 96 return true 97 } 98 return false 99 } 100 101 services := option.Services 102 // 每一个 polaris service 对应一个 envoy cluster 103 for svcKey, svc := range services { 104 if ignore(svcKey) { 105 continue 106 } 107 c := cds.makeCluster(svc, direction) 108 switch option.TLSMode { 109 case resource.TLSModePermissive: 110 // In permissive mode, we should use `TLSTransportSocket` to connect to mtls enabled endpoints. 111 // Or we use rawbuffer transport for those endpoints which not enabled mtls. 112 c.TransportSocketMatches = []*cluster.Cluster_TransportSocketMatch{ 113 { 114 Name: "tls-mode", 115 Match: resource.MTLSTransportSocketMatch, 116 TransportSocket: resource.MakeTLSTransportSocket(&tlstrans.UpstreamTlsContext{ 117 CommonTlsContext: resource.OutboundCommonTLSContext, 118 Sni: fmt.Sprintf(SniTemp, svc.Name, svc.Namespace), 119 }), 120 }, 121 { 122 Name: "rawbuffer", 123 Match: &structpb.Struct{}, 124 TransportSocket: &core.TransportSocket{ 125 Name: wellknown.TransportSocketRawBuffer, 126 ConfigType: &core.TransportSocket_TypedConfig{ 127 TypedConfig: resource.MustNewAny(&rawbuffer.RawBuffer{}), 128 }, 129 }, 130 }, 131 } 132 case resource.TLSModeStrict: 133 // In strict mode, we should only use `TLSTransportSocket` to connect to mtls enabled endpoints. 134 c.TransportSocketMatches = []*cluster.Cluster_TransportSocketMatch{ 135 { 136 Name: "tls-mode", 137 TransportSocket: resource.MakeTLSTransportSocket(&tlstrans.UpstreamTlsContext{ 138 CommonTlsContext: resource.OutboundCommonTLSContext, 139 Sni: fmt.Sprintf(SniTemp, svc.Name, svc.Namespace), 140 }), 141 }, 142 } 143 } 144 clusters = append(clusters, c) 145 } 146 return clusters, nil 147 } 148 149 func (cds *CDSBuilder) makeCluster(svcInfo *resource.ServiceInfo, 150 trafficDirection corev3.TrafficDirection) *cluster.Cluster { 151 152 name := resource.MakeServiceName(svcInfo.ServiceKey, trafficDirection) 153 154 return &cluster.Cluster{ 155 Name: name, 156 ConnectTimeout: ptypes.DurationProto(5 * time.Second), 157 ClusterDiscoveryType: &cluster.Cluster_Type{Type: cluster.Cluster_EDS}, 158 EdsClusterConfig: &cluster.Cluster_EdsClusterConfig{ 159 ServiceName: name, 160 EdsConfig: &core.ConfigSource{ 161 ResourceApiVersion: resourcev3.DefaultAPIVersion, 162 ConfigSourceSpecifier: &core.ConfigSource_Ads{ 163 Ads: &core.AggregatedConfigSource{}, 164 }, 165 }, 166 }, 167 LbSubsetConfig: resource.MakeLbSubsetConfig(svcInfo), 168 OutlierDetection: resource.MakeOutlierDetection(svcInfo), 169 HealthChecks: resource.MakeHealthCheck(svcInfo), 170 } 171 }