From 111cb51fc88f59d3c49bdc4405ea4c6a90ef412f Mon Sep 17 00:00:00 2001 From: Matt Keeler Date: Mon, 3 Feb 2020 09:26:47 -0500 Subject: [PATCH] =?UTF-8?q?Testing=20updates=20to=20support=20namespaced?= =?UTF-8?q?=20testing=20of=20the=20agent/xds=E2=80=A6=20(#7185)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Various testing updates to support namespaced testing of the agent/xds package * agent/proxycfg package updates to support better namespace testing --- agent/connect/generate_test.go | 2 +- agent/connect/testing_ca.go | 10 +++++++--- agent/proxycfg/state.go | 2 ++ agent/proxycfg/state_test.go | 1 + agent/proxycfg/testing.go | 4 +++- agent/structs/connect_ca.go | 3 +++ agent/xds/clusters.go | 2 +- agent/xds/server_test.go | 22 ++++++++++++++-------- sdk/testutil/testlog.go | 2 +- 9 files changed, 33 insertions(+), 15 deletions(-) diff --git a/agent/connect/generate_test.go b/agent/connect/generate_test.go index 7aad8f863..226ffd853 100644 --- a/agent/connect/generate_test.go +++ b/agent/connect/generate_test.go @@ -135,7 +135,7 @@ func TestSignatureMismatches(t *testing.T) { ca := TestCAWithKeyType(t, nil, p1.keyType, p1.keyBits) r.Equal(p1.keyType, ca.PrivateKeyType) r.Equal(p1.keyBits, ca.PrivateKeyBits) - certPEM, keyPEM, err := testLeaf(t, "foobar.service.consul", ca, p2.keyType, p2.keyBits) + certPEM, keyPEM, err := testLeaf(t, "foobar.service.consul", "default", ca, p2.keyType, p2.keyBits) r.NoError(err) _, err = ParseCert(certPEM) r.NoError(err) diff --git a/agent/connect/testing_ca.go b/agent/connect/testing_ca.go index c9ec35c9c..4b0d72288 100644 --- a/agent/connect/testing_ca.go +++ b/agent/connect/testing_ca.go @@ -168,7 +168,7 @@ func TestCAWithKeyType(t testing.T, xc *structs.CARoot, keyType string, keyBits return testCA(t, xc, keyType, keyBits) } -func testLeaf(t testing.T, service string, root *structs.CARoot, keyType string, keyBits int) (string, string, error) { +func testLeaf(t testing.T, service string, namespace string, root *structs.CARoot, keyType string, keyBits int) (string, string, error) { // Parse the CA cert and signing key from the root cert := root.SigningCert if cert == "" { @@ -186,7 +186,7 @@ func testLeaf(t testing.T, service string, root *structs.CARoot, keyType string, // Build the SPIFFE ID spiffeId := &SpiffeIDService{ Host: fmt.Sprintf("%s.consul", TestClusterID), - Namespace: "default", + Namespace: namespace, Datacenter: "dc1", Service: service, } @@ -247,12 +247,16 @@ func testLeaf(t testing.T, service string, root *structs.CARoot, keyType string, // TestLeaf returns a valid leaf certificate and it's private key for the named // service with the given CA Root. func TestLeaf(t testing.T, service string, root *structs.CARoot) (string, string) { + return TestLeafWithNamespace(t, service, "default", root) +} + +func TestLeafWithNamespace(t testing.T, service, namespace string, root *structs.CARoot) (string, string) { // Currently we only support EC leaf keys and certs even if the CA is using // RSA. We might allow Leafs to follow the signing CA key type later if we // need to for compatibility sake but this is allowed by TLS 1.2 and works with // both openssl verify (which we use as a sanity check in our tests of this // package) and Go's TLS verification. - certPEM, keyPEM, err := testLeaf(t, service, root, DefaultPrivateKeyType, DefaultPrivateKeyBits) + certPEM, keyPEM, err := testLeaf(t, service, namespace, root, DefaultPrivateKeyType, DefaultPrivateKeyBits) if err != nil { t.Fatalf(err.Error()) } diff --git a/agent/proxycfg/state.go b/agent/proxycfg/state.go index 005815143..d6203a346 100644 --- a/agent/proxycfg/state.go +++ b/agent/proxycfg/state.go @@ -607,6 +607,7 @@ func (s *state) resetWatchesFromChain( chain *structs.CompiledDiscoveryChain, snap *ConfigSnapshot, ) error { + s.logger.Trace("resetting watches for discovery chain", "id", id) if chain == nil { return fmt.Errorf("not possible to arrive here with no discovery chain") } @@ -647,6 +648,7 @@ func (s *state) resetWatchesFromChain( "upstream", id, "chain", chain.ServiceName, "target", target.ID, + "mesh-gateway-mode", target.MeshGateway.Mode, ) // We'll get endpoints from the gateway query, but the health still has diff --git a/agent/proxycfg/state_test.go b/agent/proxycfg/state_test.go index a4f47d24a..1e8b1bc4b 100644 --- a/agent/proxycfg/state_test.go +++ b/agent/proxycfg/state_test.go @@ -252,6 +252,7 @@ func genVerifyGatewayWatch(expectedDatacenter string) verifyWatchRequest { require.Equal(t, expectedDatacenter, reqReal.Datacenter) require.True(t, reqReal.UseServiceKind) require.Equal(t, structs.ServiceKindMeshGateway, reqReal.ServiceKind) + require.Equal(t, structs.DefaultEnterpriseMeta(), &reqReal.EnterpriseMeta) } } diff --git a/agent/proxycfg/testing.go b/agent/proxycfg/testing.go index 510caabf7..3b1aeb08b 100644 --- a/agent/proxycfg/testing.go +++ b/agent/proxycfg/testing.go @@ -1033,7 +1033,9 @@ func TestConfigSnapshotExposeConfig(t testing.T) *ConfigSnapshot { Address: "1.2.3.4", Port: 8080, Proxy: structs.ConnectProxyConfig{ - LocalServicePort: 8080, + DestinationServiceName: "web", + DestinationServiceID: "web", + LocalServicePort: 8080, Expose: structs.ExposeConfig{ Checks: false, Paths: []structs.ExposePath{ diff --git a/agent/structs/connect_ca.go b/agent/structs/connect_ca.go index 10f14f5e1..2e3ddb133 100644 --- a/agent/structs/connect_ca.go +++ b/agent/structs/connect_ca.go @@ -165,6 +165,9 @@ type IssuedCert struct { ValidAfter time.Time ValidBefore time.Time + // EnterpriseMeta is the Consul Enterprise specific metadata + EnterpriseMeta + RaftIndex } diff --git a/agent/xds/clusters.go b/agent/xds/clusters.go index 2ae319a5c..f8f78c846 100644 --- a/agent/xds/clusters.go +++ b/agent/xds/clusters.go @@ -260,7 +260,7 @@ func (s *Server) makeUpstreamClustersForDiscoveryChain( cfgSnap *proxycfg.ConfigSnapshot, ) ([]*envoy.Cluster, error) { if chain == nil { - return nil, fmt.Errorf("cannot create upstream cluster without discovery chain") + return nil, fmt.Errorf("cannot create upstream cluster without discovery chain for %s", upstream.Identifier()) } cfg, err := ParseUpstreamConfigNoDefaults(upstream.Config) diff --git a/agent/xds/server_test.go b/agent/xds/server_test.go index 466e902aa..251a38eb7 100644 --- a/agent/xds/server_test.go +++ b/agent/xds/server_test.go @@ -32,10 +32,11 @@ type testManager struct { } type connectAuthzResult struct { - authz bool - reason string - m *cache.ResultMeta - err error + authz bool + reason string + m *cache.ResultMeta + err error + validate func(req *structs.ConnectAuthorizeRequest) error } func newTestManager(t *testing.T) *testManager { @@ -95,6 +96,11 @@ func (m *testManager) ConnectAuthorize(token string, req *structs.ConnectAuthori m.Lock() defer m.Unlock() if res, ok := m.authz[token]; ok { + if res.validate != nil { + if err := res.validate(req); err != nil { + return false, "", nil, err + } + } return res.authz, res.reason, res.m, res.err } // Default allow but with reason that won't match by accident in a test case @@ -717,7 +723,7 @@ func TestServer_Check(t *testing.T) { name: "auth allowed", source: "web", dest: "db", - authzResult: connectAuthzResult{true, "default allow", nil, nil}, + authzResult: connectAuthzResult{true, "default allow", nil, nil, nil}, wantDenied: false, wantReason: "default allow", }, @@ -725,7 +731,7 @@ func TestServer_Check(t *testing.T) { name: "auth denied", source: "web", dest: "db", - authzResult: connectAuthzResult{false, "default deny", nil, nil}, + authzResult: connectAuthzResult{false, "default deny", nil, nil, nil}, wantDenied: true, wantReason: "default deny", }, @@ -765,7 +771,7 @@ func TestServer_Check(t *testing.T) { name: "ACL not got permission for authz call", source: "web", dest: "db", - authzResult: connectAuthzResult{false, "", nil, acl.ErrPermissionDenied}, + authzResult: connectAuthzResult{false, "", nil, acl.ErrPermissionDenied, nil}, wantErr: true, wantErrCode: codes.PermissionDenied, }, @@ -773,7 +779,7 @@ func TestServer_Check(t *testing.T) { name: "Random error running authz", source: "web", dest: "db", - authzResult: connectAuthzResult{false, "", nil, errors.New("gremlin attack")}, + authzResult: connectAuthzResult{false, "", nil, errors.New("gremlin attack"), nil}, wantErr: true, wantErrCode: codes.Internal, }, diff --git a/sdk/testutil/testlog.go b/sdk/testutil/testlog.go index 12d8dde94..154c1fc56 100644 --- a/sdk/testutil/testlog.go +++ b/sdk/testutil/testlog.go @@ -37,7 +37,7 @@ func Logger(t testing.TB) hclog.InterceptLogger { func LoggerWithOutput(t testing.TB, output io.Writer) hclog.InterceptLogger { return hclog.NewInterceptLogger(&hclog.LoggerOptions{ Name: t.Name(), - Level: hclog.Debug, + Level: hclog.Trace, Output: output, }) }