-
Notifications
You must be signed in to change notification settings - Fork 4.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
xds: don't fail channel/server startup when xds creds is specified, but bootstrap is missing certificate providers #6848
Conversation
…ut bootstrap is missing certificate providers
Codecov Report
Additional details and impacted files@@ Coverage Diff @@
## master #6848 +/- ##
==========================================
+ Coverage 83.43% 83.53% +0.09%
==========================================
Files 286 286
Lines 30801 30756 -45
==========================================
- Hits 25699 25692 -7
+ Misses 4028 3993 -35
+ Partials 1074 1071 -3
|
Can you please add an e2e test as to what the behavior should be e2e? (i.e. not fail, resolver NACKs, we handle in a graceful case). It used to be to fail, now what should it be? I see the component test for resolver only |
Server and Client side please for e2e test. Also, we only process security config from top level cluster incorrectly now, it needs to be for each specific cluster. |
1363ae5
to
6d26f6f
Compare
Added e2e style tests for both client and server now. PTAL. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will need to rebase my server fix onto this PR. Hopefully I can get that PR out by Thurs so you can take at least once pass before your leave for me to get back to next year.
// Initialize an xDS-enabled gRPC server and register the stubServer on it. | ||
// Pass it a mode change server option that pushes on a channel the mode | ||
// changes to "not serving". | ||
modeCh := make(chan struct{}) | ||
modeChangeOpt := xds.ServingModeCallback(func(addr net.Addr, args xds.ServingModeChangeArgs) { | ||
if args.Mode == connectivity.ServingModeServing { | ||
close(modeCh) | ||
} | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would rather call modeCh. Also, this sends only once by closing it (and will panic if you close twice). Thinking about it, I made this an event for my server side e2e tests for the server side fix serving := grpcsync.NewEvent()...if args.Mode == connectivity.ServingModeServing {
serving.Fire()
}. I think that this semantically makes more sense here (and below).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would rather call modeCh
It is called modeCh
already. Don't understand this comment.
Also, this sends only once by closing it (and will panic if you close twice).
Since, we don't expect this to even happen once, I'm not too worried about a double close.
I think that this semantically makes more sense here (and below)
The grpcsync.Event
provides a way to spot check if the event has fired and a way to block on the event firing. Since we only need the latter here, I feel a channel is more appropriate and it does not make the code harder to read in anyway. So, I would like to stick to using a channel here, unless you have a very good reason for using a grpcsync.Event
instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry servingModeCh. Hmmmm I guess that a channel does make sense here since this is something we expect not to happen vs. to happen (i.e. wait till serving until RPC happens)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed to servingModeCh
.
@@ -86,71 +83,36 @@ func (s) TestResolverBuilder_ClientCreationFails_NoBootstap(t *testing.T) { | |||
} | |||
} | |||
|
|||
// Tests the resolver builder's Build() method with different xDS bootstrap | |||
// configurations. | |||
func (s) TestResolverBuilder_DifferentBootstrapConfigs(t *testing.T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Optional: leave a t-test in case we add more failure modes for resolver construction in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is a t-test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah - Menghan/Doug described the functionality of defining test cases, then looping through each of them as a unity test as a "t-test'. So keep a slice of length 1. Optional though.
}}}}}, | ||
}, | ||
HttpFilters: []*v3httppb.HttpFilter{e2e.RouterHTTPFilter}, | ||
} | ||
ts := &v3corepb.TransportSocket{ | ||
Name: "envoy.transport_sockets.tls", | ||
ConfigType: &v3corepb.TransportSocket_TypedConfig{ | ||
TypedConfig: testutils.MarshalAny(t, &v3tlspb.DownstreamTlsContext{ | ||
RequireClientCertificate: &wrapperspb.BoolValue{Value: true}, | ||
CommonTlsContext: &v3tlspb.CommonTlsContext{ | ||
TlsCertificateCertificateProviderInstance: &v3tlspb.CommonTlsContext_CertificateProviderInstance{ | ||
InstanceName: "non-existent-certificate-provider", | ||
}, | ||
ValidationContextType: &v3tlspb.CommonTlsContext_ValidationContextCertificateProviderInstance{ | ||
ValidationContextCertificateProviderInstance: &v3tlspb.CommonTlsContext_CertificateProviderInstance{ | ||
InstanceName: "non-existent-certificate-provider", | ||
}, | ||
}, | ||
}, | ||
}), | ||
}, | ||
} | ||
resource2 := &v3listenerpb.Listener{ | ||
Name: fmt.Sprintf(e2e.ServerListenerResourceNameTemplate, net.JoinHostPort(host2, strconv.Itoa(int(port2)))), | ||
Address: &v3corepb.Address{ | ||
Address: &v3corepb.Address_SocketAddress{ | ||
SocketAddress: &v3corepb.SocketAddress{ | ||
Address: host2, | ||
PortSpecifier: &v3corepb.SocketAddress_PortValue{ | ||
PortValue: port2, | ||
}, | ||
}, | ||
}, | ||
}, | ||
FilterChains: []*v3listenerpb.FilterChain{ | ||
{ | ||
Name: "v4-wildcard", | ||
FilterChainMatch: &v3listenerpb.FilterChainMatch{ | ||
PrefixRanges: []*v3corepb.CidrRange{ | ||
{ | ||
AddressPrefix: "0.0.0.0", | ||
PrefixLen: &wrapperspb.UInt32Value{ | ||
Value: uint32(0), | ||
}, | ||
}, | ||
}, | ||
SourceType: v3listenerpb.FilterChainMatch_SAME_IP_OR_LOOPBACK, | ||
SourcePrefixRanges: []*v3corepb.CidrRange{ | ||
{ | ||
AddressPrefix: "0.0.0.0", | ||
PrefixLen: &wrapperspb.UInt32Value{ | ||
Value: uint32(0), | ||
}, | ||
}, | ||
}, | ||
}, | ||
Filters: []*v3listenerpb.Filter{ | ||
{ | ||
Name: "filter-1", | ||
ConfigType: &v3listenerpb.Filter_TypedConfig{TypedConfig: testutils.MarshalAny(t, hcm)}, | ||
}, | ||
}, | ||
TransportSocket: ts, | ||
}, | ||
{ | ||
Name: "v6-wildcard", | ||
FilterChainMatch: &v3listenerpb.FilterChainMatch{ | ||
PrefixRanges: []*v3corepb.CidrRange{ | ||
{ | ||
AddressPrefix: "::", | ||
PrefixLen: &wrapperspb.UInt32Value{ | ||
Value: uint32(0), | ||
}, | ||
}, | ||
}, | ||
SourceType: v3listenerpb.FilterChainMatch_SAME_IP_OR_LOOPBACK, | ||
SourcePrefixRanges: []*v3corepb.CidrRange{ | ||
{ | ||
AddressPrefix: "::", | ||
PrefixLen: &wrapperspb.UInt32Value{ | ||
Value: uint32(0), | ||
}, | ||
}, | ||
}, | ||
}, | ||
Filters: []*v3listenerpb.Filter{ | ||
{ | ||
Name: "filter-1", | ||
ConfigType: &v3listenerpb.Filter_TypedConfig{TypedConfig: testutils.MarshalAny(t, hcm)}, | ||
}, | ||
}, | ||
TransportSocket: ts, | ||
}, | ||
}, | ||
} | ||
resources := e2e.UpdateOptions{ | ||
NodeID: nodeID, | ||
Listeners: []*v3listenerpb.Listener{resource1, resource2}, | ||
SkipValidation: true, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a super long inline block of xDS resources. Is there not e2e helpers for these? Should we refactor some of the e2e helpers if not to pull out common functionality for these?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not used anywhere else so far, so we haven't needed helpers for this. But if it turns out that you will need something like this for your server side tests, maybe we can pull it out at that point. But its going to be a bit of work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if _, err := client.EmptyCall(sCtx, &testpb.Empty{}); status.Code(err) != codes.DeadlineExceeded { | ||
t.Fatalf("EmptyCall() failed: %v", err) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ohhhh right, I was thinking as if my change was already in master with respect to Accept() + Close(), and not blocking as it is now. I'll probably switch this over (and I have tests for this Accept() + Close() - I thought hard about the invariant of a signal that a connection was Accepted + Closed - UNAVAILABLE with error string sgtm).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
// server. The management server responds with two listener resources: | ||
// 1. contains valid security configuration pointing to the certificate provider | ||
// instance specified in the bootstrap | ||
// 3. contains invalid security configuration pointing to a non-existent |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DOne.
We currently have checks in the xDS resolver and xDS-enabled gRPC server that verify that if xDS credentials are specified by the user, then the associated certificate providers configuration in the bootstrap is non-empty. If the check fails, then channel/server start-up fails. This is broken for a number of reasons:
This PR fixes #6756, and brings the grpc-go implementation to be in sync with C-core and Java.
RELEASE NOTES: