github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/grpc/xds/internal/testutils/e2e/clientresources.go (about) 1 /* 2 * 3 * Copyright 2021 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 package e2e 20 21 import ( 22 "fmt" 23 "net" 24 "strconv" 25 26 "github.com/golang/protobuf/proto" 27 "github.com/hxx258456/ccgo/go-control-plane/pkg/wellknown" 28 "github.com/hxx258456/ccgo/grpc/internal/testutils" 29 30 wrapperspb "github.com/golang/protobuf/ptypes/wrappers" 31 v3clusterpb "github.com/hxx258456/ccgo/go-control-plane/envoy/config/cluster/v3" 32 v3corepb "github.com/hxx258456/ccgo/go-control-plane/envoy/config/core/v3" 33 v3endpointpb "github.com/hxx258456/ccgo/go-control-plane/envoy/config/endpoint/v3" 34 v3listenerpb "github.com/hxx258456/ccgo/go-control-plane/envoy/config/listener/v3" 35 v3routepb "github.com/hxx258456/ccgo/go-control-plane/envoy/config/route/v3" 36 v3routerpb "github.com/hxx258456/ccgo/go-control-plane/envoy/extensions/filters/http/router/v3" 37 v3httppb "github.com/hxx258456/ccgo/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" 38 v3tlspb "github.com/hxx258456/ccgo/go-control-plane/envoy/extensions/transport_sockets/tls/v3" 39 ) 40 41 const ( 42 // ServerListenerResourceNameTemplate is the Listener resource name template 43 // used on the server side. 44 ServerListenerResourceNameTemplate = "grpc/server?xds.resource.listening_address=%s" 45 // ClientSideCertProviderInstance is the certificate provider instance name 46 // used in the Cluster resource on the client side. 47 ClientSideCertProviderInstance = "client-side-certificate-provider-instance" 48 // ServerSideCertProviderInstance is the certificate provider instance name 49 // used in the Listener resource on the server side. 50 ServerSideCertProviderInstance = "server-side-certificate-provider-instance" 51 ) 52 53 // SecurityLevel allows the test to control the security level to be used in the 54 // resource returned by this package. 55 type SecurityLevel int 56 57 const ( 58 // SecurityLevelNone is used when no security configuration is required. 59 SecurityLevelNone SecurityLevel = iota 60 // SecurityLevelTLS is used when security configuration corresponding to TLS 61 // is required. Only the server presents an identity certificate in this 62 // configuration. 63 SecurityLevelTLS 64 // SecurityLevelMTLS is used when security ocnfiguration corresponding to 65 // mTLS is required. Both client and server present identity certificates in 66 // this configuration. 67 SecurityLevelMTLS 68 ) 69 70 // ResourceParams wraps the arguments to be passed to DefaultClientResources. 71 type ResourceParams struct { 72 // DialTarget is the client's dial target. This is used as the name of the 73 // Listener resource. 74 DialTarget string 75 // NodeID is the id of the xdsClient to which this update is to be pushed. 76 NodeID string 77 // Host is the host of the default Endpoint resource. 78 Host string 79 // port is the port of the default Endpoint resource. 80 Port uint32 81 // SecLevel controls the security configuration in the Cluster resource. 82 SecLevel SecurityLevel 83 } 84 85 // DefaultClientResources returns a set of resources (LDS, RDS, CDS, EDS) for a 86 // client to generically connect to one server. 87 func DefaultClientResources(params ResourceParams) UpdateOptions { 88 routeConfigName := "route-" + params.DialTarget 89 clusterName := "cluster-" + params.DialTarget 90 endpointsName := "endpoints-" + params.DialTarget 91 return UpdateOptions{ 92 NodeID: params.NodeID, 93 Listeners: []*v3listenerpb.Listener{DefaultClientListener(params.DialTarget, routeConfigName)}, 94 Routes: []*v3routepb.RouteConfiguration{DefaultRouteConfig(routeConfigName, params.DialTarget, clusterName)}, 95 Clusters: []*v3clusterpb.Cluster{DefaultCluster(clusterName, endpointsName, params.SecLevel)}, 96 Endpoints: []*v3endpointpb.ClusterLoadAssignment{DefaultEndpoint(endpointsName, params.Host, []uint32{params.Port})}, 97 } 98 } 99 100 // RouterHTTPFilter is the HTTP Filter configuration for the Router filter. 101 var RouterHTTPFilter = HTTPFilter("router", &v3routerpb.Router{}) 102 103 // DefaultClientListener returns a basic xds Listener resource to be used on 104 // the client side. 105 func DefaultClientListener(target, routeName string) *v3listenerpb.Listener { 106 hcm := testutils.MarshalAny(&v3httppb.HttpConnectionManager{ 107 RouteSpecifier: &v3httppb.HttpConnectionManager_Rds{Rds: &v3httppb.Rds{ 108 ConfigSource: &v3corepb.ConfigSource{ 109 ConfigSourceSpecifier: &v3corepb.ConfigSource_Ads{Ads: &v3corepb.AggregatedConfigSource{}}, 110 }, 111 RouteConfigName: routeName, 112 }}, 113 HttpFilters: []*v3httppb.HttpFilter{HTTPFilter("router", &v3routerpb.Router{})}, // router fields are unused by grpc 114 }) 115 return &v3listenerpb.Listener{ 116 Name: target, 117 ApiListener: &v3listenerpb.ApiListener{ApiListener: hcm}, 118 FilterChains: []*v3listenerpb.FilterChain{{ 119 Name: "filter-chain-name", 120 Filters: []*v3listenerpb.Filter{{ 121 Name: wellknown.HTTPConnectionManager, 122 ConfigType: &v3listenerpb.Filter_TypedConfig{TypedConfig: hcm}, 123 }}, 124 }}, 125 } 126 } 127 128 // DefaultServerListener returns a basic xds Listener resource to be used on 129 // the server side. 130 func DefaultServerListener(host string, port uint32, secLevel SecurityLevel) *v3listenerpb.Listener { 131 var tlsContext *v3tlspb.DownstreamTlsContext 132 switch secLevel { 133 case SecurityLevelNone: 134 case SecurityLevelTLS: 135 tlsContext = &v3tlspb.DownstreamTlsContext{ 136 CommonTlsContext: &v3tlspb.CommonTlsContext{ 137 TlsCertificateCertificateProviderInstance: &v3tlspb.CommonTlsContext_CertificateProviderInstance{ 138 InstanceName: ServerSideCertProviderInstance, 139 }, 140 }, 141 } 142 case SecurityLevelMTLS: 143 tlsContext = &v3tlspb.DownstreamTlsContext{ 144 RequireClientCertificate: &wrapperspb.BoolValue{Value: true}, 145 CommonTlsContext: &v3tlspb.CommonTlsContext{ 146 TlsCertificateCertificateProviderInstance: &v3tlspb.CommonTlsContext_CertificateProviderInstance{ 147 InstanceName: ServerSideCertProviderInstance, 148 }, 149 ValidationContextType: &v3tlspb.CommonTlsContext_ValidationContextCertificateProviderInstance{ 150 ValidationContextCertificateProviderInstance: &v3tlspb.CommonTlsContext_CertificateProviderInstance{ 151 InstanceName: ServerSideCertProviderInstance, 152 }, 153 }, 154 }, 155 } 156 } 157 158 var ts *v3corepb.TransportSocket 159 if tlsContext != nil { 160 ts = &v3corepb.TransportSocket{ 161 Name: "envoy.transport_sockets.tls", 162 ConfigType: &v3corepb.TransportSocket_TypedConfig{ 163 TypedConfig: testutils.MarshalAny(tlsContext), 164 }, 165 } 166 } 167 return &v3listenerpb.Listener{ 168 Name: fmt.Sprintf(ServerListenerResourceNameTemplate, net.JoinHostPort(host, strconv.Itoa(int(port)))), 169 Address: &v3corepb.Address{ 170 Address: &v3corepb.Address_SocketAddress{ 171 SocketAddress: &v3corepb.SocketAddress{ 172 Address: host, 173 PortSpecifier: &v3corepb.SocketAddress_PortValue{ 174 PortValue: port, 175 }, 176 }, 177 }, 178 }, 179 FilterChains: []*v3listenerpb.FilterChain{ 180 { 181 Name: "v4-wildcard", 182 FilterChainMatch: &v3listenerpb.FilterChainMatch{ 183 PrefixRanges: []*v3corepb.CidrRange{ 184 { 185 AddressPrefix: "0.0.0.0", 186 PrefixLen: &wrapperspb.UInt32Value{ 187 Value: uint32(0), 188 }, 189 }, 190 }, 191 SourceType: v3listenerpb.FilterChainMatch_SAME_IP_OR_LOOPBACK, 192 SourcePrefixRanges: []*v3corepb.CidrRange{ 193 { 194 AddressPrefix: "0.0.0.0", 195 PrefixLen: &wrapperspb.UInt32Value{ 196 Value: uint32(0), 197 }, 198 }, 199 }, 200 }, 201 Filters: []*v3listenerpb.Filter{ 202 { 203 Name: "filter-1", 204 ConfigType: &v3listenerpb.Filter_TypedConfig{ 205 TypedConfig: testutils.MarshalAny(&v3httppb.HttpConnectionManager{ 206 RouteSpecifier: &v3httppb.HttpConnectionManager_RouteConfig{ 207 RouteConfig: &v3routepb.RouteConfiguration{ 208 Name: "routeName", 209 VirtualHosts: []*v3routepb.VirtualHost{{ 210 // This "*" string matches on any incoming authority. This is to ensure any 211 // incoming RPC matches to Route_NonForwardingAction and will proceed as 212 // normal. 213 Domains: []string{"*"}, 214 Routes: []*v3routepb.Route{{ 215 Match: &v3routepb.RouteMatch{ 216 PathSpecifier: &v3routepb.RouteMatch_Prefix{Prefix: "/"}, 217 }, 218 Action: &v3routepb.Route_NonForwardingAction{}, 219 }}}}}, 220 }, 221 HttpFilters: []*v3httppb.HttpFilter{RouterHTTPFilter}, 222 }), 223 }, 224 }, 225 }, 226 TransportSocket: ts, 227 }, 228 { 229 Name: "v6-wildcard", 230 FilterChainMatch: &v3listenerpb.FilterChainMatch{ 231 PrefixRanges: []*v3corepb.CidrRange{ 232 { 233 AddressPrefix: "::", 234 PrefixLen: &wrapperspb.UInt32Value{ 235 Value: uint32(0), 236 }, 237 }, 238 }, 239 SourceType: v3listenerpb.FilterChainMatch_SAME_IP_OR_LOOPBACK, 240 SourcePrefixRanges: []*v3corepb.CidrRange{ 241 { 242 AddressPrefix: "::", 243 PrefixLen: &wrapperspb.UInt32Value{ 244 Value: uint32(0), 245 }, 246 }, 247 }, 248 }, 249 Filters: []*v3listenerpb.Filter{ 250 { 251 Name: "filter-1", 252 ConfigType: &v3listenerpb.Filter_TypedConfig{ 253 TypedConfig: testutils.MarshalAny(&v3httppb.HttpConnectionManager{ 254 RouteSpecifier: &v3httppb.HttpConnectionManager_RouteConfig{ 255 RouteConfig: &v3routepb.RouteConfiguration{ 256 Name: "routeName", 257 VirtualHosts: []*v3routepb.VirtualHost{{ 258 // This "*" string matches on any incoming authority. This is to ensure any 259 // incoming RPC matches to Route_NonForwardingAction and will proceed as 260 // normal. 261 Domains: []string{"*"}, 262 Routes: []*v3routepb.Route{{ 263 Match: &v3routepb.RouteMatch{ 264 PathSpecifier: &v3routepb.RouteMatch_Prefix{Prefix: "/"}, 265 }, 266 Action: &v3routepb.Route_NonForwardingAction{}, 267 }}}}}, 268 }, 269 HttpFilters: []*v3httppb.HttpFilter{RouterHTTPFilter}, 270 }), 271 }, 272 }, 273 }, 274 TransportSocket: ts, 275 }, 276 }, 277 } 278 } 279 280 // HTTPFilter constructs an xds HttpFilter with the provided name and config. 281 func HTTPFilter(name string, config proto.Message) *v3httppb.HttpFilter { 282 return &v3httppb.HttpFilter{ 283 Name: name, 284 ConfigType: &v3httppb.HttpFilter_TypedConfig{ 285 TypedConfig: testutils.MarshalAny(config), 286 }, 287 } 288 } 289 290 // DefaultRouteConfig returns a basic xds RouteConfig resource. 291 func DefaultRouteConfig(routeName, ldsTarget, clusterName string) *v3routepb.RouteConfiguration { 292 return &v3routepb.RouteConfiguration{ 293 Name: routeName, 294 VirtualHosts: []*v3routepb.VirtualHost{{ 295 Domains: []string{ldsTarget}, 296 Routes: []*v3routepb.Route{{ 297 Match: &v3routepb.RouteMatch{PathSpecifier: &v3routepb.RouteMatch_Prefix{Prefix: "/"}}, 298 Action: &v3routepb.Route_Route{Route: &v3routepb.RouteAction{ 299 ClusterSpecifier: &v3routepb.RouteAction_Cluster{Cluster: clusterName}, 300 }}, 301 }}, 302 }}, 303 } 304 } 305 306 // DefaultCluster returns a basic xds Cluster resource. 307 func DefaultCluster(clusterName, edsServiceName string, secLevel SecurityLevel) *v3clusterpb.Cluster { 308 var tlsContext *v3tlspb.UpstreamTlsContext 309 switch secLevel { 310 case SecurityLevelNone: 311 case SecurityLevelTLS: 312 tlsContext = &v3tlspb.UpstreamTlsContext{ 313 CommonTlsContext: &v3tlspb.CommonTlsContext{ 314 ValidationContextType: &v3tlspb.CommonTlsContext_ValidationContextCertificateProviderInstance{ 315 ValidationContextCertificateProviderInstance: &v3tlspb.CommonTlsContext_CertificateProviderInstance{ 316 InstanceName: ClientSideCertProviderInstance, 317 }, 318 }, 319 }, 320 } 321 case SecurityLevelMTLS: 322 tlsContext = &v3tlspb.UpstreamTlsContext{ 323 CommonTlsContext: &v3tlspb.CommonTlsContext{ 324 ValidationContextType: &v3tlspb.CommonTlsContext_ValidationContextCertificateProviderInstance{ 325 ValidationContextCertificateProviderInstance: &v3tlspb.CommonTlsContext_CertificateProviderInstance{ 326 InstanceName: ClientSideCertProviderInstance, 327 }, 328 }, 329 TlsCertificateCertificateProviderInstance: &v3tlspb.CommonTlsContext_CertificateProviderInstance{ 330 InstanceName: ClientSideCertProviderInstance, 331 }, 332 }, 333 } 334 } 335 336 cluster := &v3clusterpb.Cluster{ 337 Name: clusterName, 338 ClusterDiscoveryType: &v3clusterpb.Cluster_Type{Type: v3clusterpb.Cluster_EDS}, 339 EdsClusterConfig: &v3clusterpb.Cluster_EdsClusterConfig{ 340 EdsConfig: &v3corepb.ConfigSource{ 341 ConfigSourceSpecifier: &v3corepb.ConfigSource_Ads{ 342 Ads: &v3corepb.AggregatedConfigSource{}, 343 }, 344 }, 345 ServiceName: edsServiceName, 346 }, 347 LbPolicy: v3clusterpb.Cluster_ROUND_ROBIN, 348 } 349 if tlsContext != nil { 350 cluster.TransportSocket = &v3corepb.TransportSocket{ 351 Name: "envoy.transport_sockets.tls", 352 ConfigType: &v3corepb.TransportSocket_TypedConfig{ 353 TypedConfig: testutils.MarshalAny(tlsContext), 354 }, 355 } 356 } 357 return cluster 358 } 359 360 // DefaultEndpoint returns a basic xds Endpoint resource. 361 func DefaultEndpoint(clusterName string, host string, ports []uint32) *v3endpointpb.ClusterLoadAssignment { 362 var lbEndpoints []*v3endpointpb.LbEndpoint 363 for _, port := range ports { 364 lbEndpoints = append(lbEndpoints, &v3endpointpb.LbEndpoint{ 365 HostIdentifier: &v3endpointpb.LbEndpoint_Endpoint{Endpoint: &v3endpointpb.Endpoint{ 366 Address: &v3corepb.Address{Address: &v3corepb.Address_SocketAddress{ 367 SocketAddress: &v3corepb.SocketAddress{ 368 Protocol: v3corepb.SocketAddress_TCP, 369 Address: host, 370 PortSpecifier: &v3corepb.SocketAddress_PortValue{PortValue: port}}, 371 }}, 372 }}, 373 }) 374 } 375 return &v3endpointpb.ClusterLoadAssignment{ 376 ClusterName: clusterName, 377 Endpoints: []*v3endpointpb.LocalityLbEndpoints{{ 378 Locality: &v3corepb.Locality{SubZone: "subzone"}, 379 LbEndpoints: lbEndpoints, 380 LoadBalancingWeight: &wrapperspb.UInt32Value{Value: 1}, 381 Priority: 0, 382 }}, 383 } 384 }