github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/grpc/xds/internal/test/xds_security_config_nack_test.go (about) 1 //go:build !386 2 // +build !386 3 4 /* 5 * 6 * Copyright 2021 gRPC authors. 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 * 20 */ 21 22 package xds_test 23 24 import ( 25 "context" 26 "fmt" 27 "testing" 28 29 grpc "github.com/hxx258456/ccgo/grpc" 30 "github.com/hxx258456/ccgo/grpc/credentials/insecure" 31 xdscreds "github.com/hxx258456/ccgo/grpc/credentials/xds" 32 "github.com/hxx258456/ccgo/grpc/internal/testutils" 33 "github.com/hxx258456/ccgo/grpc/xds/internal/testutils/e2e" 34 35 v3corepb "github.com/hxx258456/ccgo/go-control-plane/envoy/config/core/v3" 36 v3tlspb "github.com/hxx258456/ccgo/go-control-plane/envoy/extensions/transport_sockets/tls/v3" 37 testpb "github.com/hxx258456/ccgo/grpc/test/grpc_testing" 38 ) 39 40 func (s) TestUnmarshalListener_WithUpdateValidatorFunc(t *testing.T) { 41 const ( 42 serviceName = "my-service-client-side-xds" 43 missingIdentityProviderInstance = "missing-identity-provider-instance" 44 missingRootProviderInstance = "missing-root-provider-instance" 45 ) 46 managementServer, nodeID, bootstrapContents, resolver, cleanup1 := setupManagementServer(t) 47 defer cleanup1() 48 49 lis, cleanup2 := setupGRPCServer(t, bootstrapContents) 50 defer cleanup2() 51 52 // Grab the host and port of the server and create client side xDS 53 // resources corresponding to it. 54 host, port, err := hostPortFromListener(lis) 55 if err != nil { 56 t.Fatalf("failed to retrieve host and port of server: %v", err) 57 } 58 59 // Create xDS resources to be consumed on the client side. This 60 // includes the listener, route configuration, cluster (with 61 // security configuration) and endpoint resources. 62 resources := e2e.DefaultClientResources(e2e.ResourceParams{ 63 DialTarget: serviceName, 64 NodeID: nodeID, 65 Host: host, 66 Port: port, 67 SecLevel: e2e.SecurityLevelMTLS, 68 }) 69 70 tests := []struct { 71 name string 72 securityConfig *v3corepb.TransportSocket 73 wantErr bool 74 }{ 75 { 76 name: "both identity and root providers are not present in bootstrap", 77 securityConfig: &v3corepb.TransportSocket{ 78 Name: "envoy.transport_sockets.tls", 79 ConfigType: &v3corepb.TransportSocket_TypedConfig{ 80 TypedConfig: testutils.MarshalAny(&v3tlspb.DownstreamTlsContext{ 81 CommonTlsContext: &v3tlspb.CommonTlsContext{ 82 TlsCertificateProviderInstance: &v3tlspb.CertificateProviderPluginInstance{ 83 InstanceName: missingIdentityProviderInstance, 84 }, 85 ValidationContextType: &v3tlspb.CommonTlsContext_ValidationContext{ 86 ValidationContext: &v3tlspb.CertificateValidationContext{ 87 CaCertificateProviderInstance: &v3tlspb.CertificateProviderPluginInstance{ 88 InstanceName: missingRootProviderInstance, 89 }, 90 }, 91 }, 92 }, 93 }), 94 }, 95 }, 96 wantErr: true, 97 }, 98 { 99 name: "only identity provider is not present in bootstrap", 100 securityConfig: &v3corepb.TransportSocket{ 101 Name: "envoy.transport_sockets.tls", 102 ConfigType: &v3corepb.TransportSocket_TypedConfig{ 103 TypedConfig: testutils.MarshalAny(&v3tlspb.DownstreamTlsContext{ 104 CommonTlsContext: &v3tlspb.CommonTlsContext{ 105 TlsCertificateProviderInstance: &v3tlspb.CertificateProviderPluginInstance{ 106 InstanceName: missingIdentityProviderInstance, 107 }, 108 ValidationContextType: &v3tlspb.CommonTlsContext_ValidationContext{ 109 ValidationContext: &v3tlspb.CertificateValidationContext{ 110 CaCertificateProviderInstance: &v3tlspb.CertificateProviderPluginInstance{ 111 InstanceName: e2e.ServerSideCertProviderInstance, 112 }, 113 }, 114 }, 115 }, 116 }), 117 }, 118 }, 119 wantErr: true, 120 }, 121 { 122 name: "only root provider is not present in bootstrap", 123 securityConfig: &v3corepb.TransportSocket{ 124 Name: "envoy.transport_sockets.tls", 125 ConfigType: &v3corepb.TransportSocket_TypedConfig{ 126 TypedConfig: testutils.MarshalAny(&v3tlspb.DownstreamTlsContext{ 127 CommonTlsContext: &v3tlspb.CommonTlsContext{ 128 TlsCertificateProviderInstance: &v3tlspb.CertificateProviderPluginInstance{ 129 InstanceName: e2e.ServerSideCertProviderInstance, 130 }, 131 ValidationContextType: &v3tlspb.CommonTlsContext_ValidationContext{ 132 ValidationContext: &v3tlspb.CertificateValidationContext{ 133 CaCertificateProviderInstance: &v3tlspb.CertificateProviderPluginInstance{ 134 InstanceName: missingRootProviderInstance, 135 }, 136 }, 137 }, 138 }, 139 }), 140 }, 141 }, 142 wantErr: true, 143 }, 144 { 145 name: "both identity and root providers are present in bootstrap", 146 securityConfig: &v3corepb.TransportSocket{ 147 Name: "envoy.transport_sockets.tls", 148 ConfigType: &v3corepb.TransportSocket_TypedConfig{ 149 TypedConfig: testutils.MarshalAny(&v3tlspb.DownstreamTlsContext{ 150 CommonTlsContext: &v3tlspb.CommonTlsContext{ 151 TlsCertificateProviderInstance: &v3tlspb.CertificateProviderPluginInstance{ 152 InstanceName: e2e.ServerSideCertProviderInstance, 153 }, 154 ValidationContextType: &v3tlspb.CommonTlsContext_ValidationContext{ 155 ValidationContext: &v3tlspb.CertificateValidationContext{ 156 CaCertificateProviderInstance: &v3tlspb.CertificateProviderPluginInstance{ 157 InstanceName: e2e.ServerSideCertProviderInstance, 158 }, 159 }, 160 }, 161 }, 162 }), 163 }, 164 }, 165 wantErr: false, 166 }, 167 } 168 169 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 170 defer cancel() 171 for _, test := range tests { 172 t.Run(test.name, func(t *testing.T) { 173 // Create an inbound xDS listener resource for the server side. 174 inboundLis := e2e.DefaultServerListener(host, port, e2e.SecurityLevelMTLS) 175 for _, fc := range inboundLis.GetFilterChains() { 176 fc.TransportSocket = test.securityConfig 177 } 178 179 // Setup the management server with client and server resources. 180 if len(resources.Listeners) == 1 { 181 resources.Listeners = append(resources.Listeners, inboundLis) 182 } else { 183 resources.Listeners[1] = inboundLis 184 } 185 if err := managementServer.Update(ctx, resources); err != nil { 186 t.Fatal(err) 187 } 188 189 // Create client-side xDS credentials with an insecure fallback. 190 creds, err := xdscreds.NewClientCredentials(xdscreds.ClientOptions{FallbackCreds: insecure.NewCredentials()}) 191 if err != nil { 192 t.Fatal(err) 193 } 194 195 // Create a ClientConn with the xds scheme and make an RPC. 196 cc, err := grpc.DialContext(ctx, fmt.Sprintf("xds:///%s", serviceName), grpc.WithTransportCredentials(creds), grpc.WithResolvers(resolver)) 197 if err != nil { 198 t.Fatalf("failed to dial local test server: %v", err) 199 } 200 defer cc.Close() 201 202 // Make a context with a shorter timeout from the top level test 203 // context for cases where we expect failures. 204 timeout := defaultTestTimeout 205 if test.wantErr { 206 timeout = defaultTestShortTimeout 207 } 208 ctx2, cancel2 := context.WithTimeout(ctx, timeout) 209 defer cancel2() 210 client := testpb.NewTestServiceClient(cc) 211 if _, err := client.EmptyCall(ctx2, &testpb.Empty{}, grpc.WaitForReady(true)); (err != nil) != test.wantErr { 212 t.Fatalf("EmptyCall() returned err: %v, wantErr %v", err, test.wantErr) 213 } 214 }) 215 } 216 } 217 218 func (s) TestUnmarshalCluster_WithUpdateValidatorFunc(t *testing.T) { 219 const ( 220 serviceName = "my-service-client-side-xds" 221 missingIdentityProviderInstance = "missing-identity-provider-instance" 222 missingRootProviderInstance = "missing-root-provider-instance" 223 ) 224 225 tests := []struct { 226 name string 227 securityConfig *v3corepb.TransportSocket 228 wantErr bool 229 }{ 230 { 231 name: "both identity and root providers are not present in bootstrap", 232 securityConfig: &v3corepb.TransportSocket{ 233 Name: "envoy.transport_sockets.tls", 234 ConfigType: &v3corepb.TransportSocket_TypedConfig{ 235 TypedConfig: testutils.MarshalAny(&v3tlspb.UpstreamTlsContext{ 236 CommonTlsContext: &v3tlspb.CommonTlsContext{ 237 TlsCertificateProviderInstance: &v3tlspb.CertificateProviderPluginInstance{ 238 InstanceName: missingIdentityProviderInstance, 239 }, 240 ValidationContextType: &v3tlspb.CommonTlsContext_ValidationContext{ 241 ValidationContext: &v3tlspb.CertificateValidationContext{ 242 CaCertificateProviderInstance: &v3tlspb.CertificateProviderPluginInstance{ 243 InstanceName: missingRootProviderInstance, 244 }, 245 }, 246 }, 247 }, 248 }), 249 }, 250 }, 251 wantErr: true, 252 }, 253 { 254 name: "only identity provider is not present in bootstrap", 255 securityConfig: &v3corepb.TransportSocket{ 256 Name: "envoy.transport_sockets.tls", 257 ConfigType: &v3corepb.TransportSocket_TypedConfig{ 258 TypedConfig: testutils.MarshalAny(&v3tlspb.UpstreamTlsContext{ 259 CommonTlsContext: &v3tlspb.CommonTlsContext{ 260 TlsCertificateProviderInstance: &v3tlspb.CertificateProviderPluginInstance{ 261 InstanceName: missingIdentityProviderInstance, 262 }, 263 ValidationContextType: &v3tlspb.CommonTlsContext_ValidationContext{ 264 ValidationContext: &v3tlspb.CertificateValidationContext{ 265 CaCertificateProviderInstance: &v3tlspb.CertificateProviderPluginInstance{ 266 InstanceName: e2e.ClientSideCertProviderInstance, 267 }, 268 }, 269 }, 270 }, 271 }), 272 }, 273 }, 274 wantErr: true, 275 }, 276 { 277 name: "only root provider is not present in bootstrap", 278 securityConfig: &v3corepb.TransportSocket{ 279 Name: "envoy.transport_sockets.tls", 280 ConfigType: &v3corepb.TransportSocket_TypedConfig{ 281 TypedConfig: testutils.MarshalAny(&v3tlspb.UpstreamTlsContext{ 282 CommonTlsContext: &v3tlspb.CommonTlsContext{ 283 TlsCertificateProviderInstance: &v3tlspb.CertificateProviderPluginInstance{ 284 InstanceName: e2e.ClientSideCertProviderInstance, 285 }, 286 ValidationContextType: &v3tlspb.CommonTlsContext_ValidationContext{ 287 ValidationContext: &v3tlspb.CertificateValidationContext{ 288 CaCertificateProviderInstance: &v3tlspb.CertificateProviderPluginInstance{ 289 InstanceName: missingRootProviderInstance, 290 }, 291 }, 292 }, 293 }, 294 }), 295 }, 296 }, 297 wantErr: true, 298 }, 299 { 300 name: "both identity and root providers are present in bootstrap", 301 securityConfig: &v3corepb.TransportSocket{ 302 Name: "envoy.transport_sockets.tls", 303 ConfigType: &v3corepb.TransportSocket_TypedConfig{ 304 TypedConfig: testutils.MarshalAny(&v3tlspb.UpstreamTlsContext{ 305 CommonTlsContext: &v3tlspb.CommonTlsContext{ 306 TlsCertificateProviderInstance: &v3tlspb.CertificateProviderPluginInstance{ 307 InstanceName: e2e.ClientSideCertProviderInstance, 308 }, 309 ValidationContextType: &v3tlspb.CommonTlsContext_ValidationContext{ 310 ValidationContext: &v3tlspb.CertificateValidationContext{ 311 CaCertificateProviderInstance: &v3tlspb.CertificateProviderPluginInstance{ 312 InstanceName: e2e.ClientSideCertProviderInstance, 313 }, 314 }, 315 }, 316 }, 317 }), 318 }, 319 }, 320 wantErr: false, 321 }, 322 } 323 324 for _, test := range tests { 325 t.Run(test.name, func(t *testing.T) { 326 // setupManagementServer() sets up a bootstrap file with certificate 327 // provider instance names: `e2e.ServerSideCertProviderInstance` and 328 // `e2e.ClientSideCertProviderInstance`. 329 managementServer, nodeID, _, resolver, cleanup1 := setupManagementServer(t) 330 defer cleanup1() 331 332 port, cleanup2 := clientSetup(t, &testService{}) 333 defer cleanup2() 334 335 // This creates a `Cluster` resource with a security config which 336 // refers to `e2e.ClientSideCertProviderInstance` for both root and 337 // identity certs. 338 resources := e2e.DefaultClientResources(e2e.ResourceParams{ 339 DialTarget: serviceName, 340 NodeID: nodeID, 341 Host: "localhost", 342 Port: port, 343 SecLevel: e2e.SecurityLevelMTLS, 344 }) 345 resources.Clusters[0].TransportSocket = test.securityConfig 346 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 347 defer cancel() 348 if err := managementServer.Update(ctx, resources); err != nil { 349 t.Fatal(err) 350 } 351 352 cc, err := grpc.Dial(fmt.Sprintf("xds:///%s", serviceName), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithResolvers(resolver)) 353 if err != nil { 354 t.Fatalf("failed to dial local test server: %v", err) 355 } 356 defer cc.Close() 357 358 // Make a context with a shorter timeout from the top level test 359 // context for cases where we expect failures. 360 timeout := defaultTestTimeout 361 if test.wantErr { 362 timeout = defaultTestShortTimeout 363 } 364 ctx2, cancel2 := context.WithTimeout(ctx, timeout) 365 defer cancel2() 366 client := testpb.NewTestServiceClient(cc) 367 if _, err := client.EmptyCall(ctx2, &testpb.Empty{}, grpc.WaitForReady(true)); (err != nil) != test.wantErr { 368 t.Fatalf("EmptyCall() returned err: %v, wantErr %v", err, test.wantErr) 369 } 370 }) 371 } 372 }