Require Connect and TLS to generate peering tokens
By requiring Connect and a gRPC TLS listener we can automatically configure TLS for all peering control-plane traffic.
This commit is contained in:
parent
a21e5799f7
commit
6ef8d329d2
|
@ -43,18 +43,6 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestLeader_PeeringSync_Lifecycle_ClientDeletion(t *testing.T) {
|
func TestLeader_PeeringSync_Lifecycle_ClientDeletion(t *testing.T) {
|
||||||
t.Run("without-tls", func(t *testing.T) {
|
|
||||||
testLeader_PeeringSync_Lifecycle_ClientDeletion(t, tlsModeNone)
|
|
||||||
})
|
|
||||||
t.Run("manual-tls", func(t *testing.T) {
|
|
||||||
testLeader_PeeringSync_Lifecycle_ClientDeletion(t, tlsModeManual)
|
|
||||||
})
|
|
||||||
t.Run("auto-tls", func(t *testing.T) {
|
|
||||||
testLeader_PeeringSync_Lifecycle_ClientDeletion(t, tlsModeAuto)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func testLeader_PeeringSync_Lifecycle_ClientDeletion(t *testing.T, mode tlsMode) {
|
|
||||||
if testing.Short() {
|
if testing.Short() {
|
||||||
t.Skip("too slow for testing.Short")
|
t.Skip("too slow for testing.Short")
|
||||||
}
|
}
|
||||||
|
@ -64,22 +52,14 @@ func testLeader_PeeringSync_Lifecycle_ClientDeletion(t *testing.T, mode tlsMode)
|
||||||
c.NodeName = "acceptor"
|
c.NodeName = "acceptor"
|
||||||
c.Datacenter = "dc1"
|
c.Datacenter = "dc1"
|
||||||
c.TLSConfig.Domain = "consul"
|
c.TLSConfig.Domain = "consul"
|
||||||
if mode == tlsModeManual {
|
c.GRPCTLSPort = freeport.GetOne(t)
|
||||||
c.ConnectEnabled = false
|
c.CAConfig = &structs.CAConfiguration{
|
||||||
c.TLSConfig.GRPC.CAFile = "../../test/hostname/CertAuth.crt"
|
ClusterID: connect.TestClusterID,
|
||||||
c.TLSConfig.GRPC.CertFile = "../../test/hostname/Bob.crt"
|
Provider: structs.ConsulCAProvider,
|
||||||
c.TLSConfig.GRPC.KeyFile = "../../test/hostname/Bob.key"
|
Config: map[string]interface{}{
|
||||||
}
|
"PrivateKey": ca.SigningKey,
|
||||||
if mode == tlsModeAuto {
|
"RootCert": ca.RootCert,
|
||||||
c.CAConfig = &structs.CAConfiguration{
|
},
|
||||||
ClusterID: connect.TestClusterID,
|
|
||||||
Provider: structs.ConsulCAProvider,
|
|
||||||
Config: map[string]interface{}{
|
|
||||||
"PrivateKey": ca.SigningKey,
|
|
||||||
"RootCert": ca.RootCert,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
testrpc.WaitForLeader(t, acceptor.RPC, "dc1")
|
testrpc.WaitForLeader(t, acceptor.RPC, "dc1")
|
||||||
|
@ -364,18 +344,6 @@ func TestLeader_PeeringSync_Lifecycle_UnexportWhileDown(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLeader_PeeringSync_Lifecycle_ServerDeletion(t *testing.T) {
|
func TestLeader_PeeringSync_Lifecycle_ServerDeletion(t *testing.T) {
|
||||||
t.Run("without-tls", func(t *testing.T) {
|
|
||||||
testLeader_PeeringSync_Lifecycle_AcceptorDeletion(t, tlsModeNone)
|
|
||||||
})
|
|
||||||
t.Run("manual-tls", func(t *testing.T) {
|
|
||||||
testLeader_PeeringSync_Lifecycle_AcceptorDeletion(t, tlsModeManual)
|
|
||||||
})
|
|
||||||
t.Run("auto-tls", func(t *testing.T) {
|
|
||||||
testLeader_PeeringSync_Lifecycle_AcceptorDeletion(t, tlsModeAuto)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func testLeader_PeeringSync_Lifecycle_AcceptorDeletion(t *testing.T, mode tlsMode) {
|
|
||||||
if testing.Short() {
|
if testing.Short() {
|
||||||
t.Skip("too slow for testing.Short")
|
t.Skip("too slow for testing.Short")
|
||||||
}
|
}
|
||||||
|
@ -385,22 +353,14 @@ func testLeader_PeeringSync_Lifecycle_AcceptorDeletion(t *testing.T, mode tlsMod
|
||||||
c.NodeName = "acceptor"
|
c.NodeName = "acceptor"
|
||||||
c.Datacenter = "dc1"
|
c.Datacenter = "dc1"
|
||||||
c.TLSConfig.Domain = "consul"
|
c.TLSConfig.Domain = "consul"
|
||||||
if mode == tlsModeManual {
|
c.GRPCTLSPort = freeport.GetOne(t)
|
||||||
c.ConnectEnabled = false
|
c.CAConfig = &structs.CAConfiguration{
|
||||||
c.TLSConfig.GRPC.CAFile = "../../test/hostname/CertAuth.crt"
|
ClusterID: connect.TestClusterID,
|
||||||
c.TLSConfig.GRPC.CertFile = "../../test/hostname/Bob.crt"
|
Provider: structs.ConsulCAProvider,
|
||||||
c.TLSConfig.GRPC.KeyFile = "../../test/hostname/Bob.key"
|
Config: map[string]interface{}{
|
||||||
}
|
"PrivateKey": ca.SigningKey,
|
||||||
if mode == tlsModeAuto {
|
"RootCert": ca.RootCert,
|
||||||
c.CAConfig = &structs.CAConfiguration{
|
},
|
||||||
ClusterID: connect.TestClusterID,
|
|
||||||
Provider: structs.ConsulCAProvider,
|
|
||||||
Config: map[string]interface{}{
|
|
||||||
"PrivateKey": ca.SigningKey,
|
|
||||||
"RootCert": ca.RootCert,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
testrpc.WaitForLeader(t, acceptor.RPC, "dc1")
|
testrpc.WaitForLeader(t, acceptor.RPC, "dc1")
|
||||||
|
@ -507,7 +467,7 @@ func TestLeader_PeeringSync_FailsForTLSError(t *testing.T) {
|
||||||
t.Run("server-name-validation", func(t *testing.T) {
|
t.Run("server-name-validation", func(t *testing.T) {
|
||||||
testLeader_PeeringSync_failsForTLSError(t, func(token *structs.PeeringToken) {
|
testLeader_PeeringSync_failsForTLSError(t, func(token *structs.PeeringToken) {
|
||||||
token.ServerName = "wrong.name"
|
token.ServerName = "wrong.name"
|
||||||
}, `transport: authentication handshake failed: x509: certificate is valid for server.dc1.consul, bob.server.dc1.consul, not wrong.name`)
|
}, `transport: authentication handshake failed: x509: certificate is valid for server.dc1.peering.11111111-2222-3333-4444-555555555555.consul, not wrong.name`)
|
||||||
})
|
})
|
||||||
t.Run("bad-ca-roots", func(t *testing.T) {
|
t.Run("bad-ca-roots", func(t *testing.T) {
|
||||||
wrongRoot, err := ioutil.ReadFile("../../test/client_certs/rootca.crt")
|
wrongRoot, err := ioutil.ReadFile("../../test/client_certs/rootca.crt")
|
||||||
|
@ -522,15 +482,20 @@ func TestLeader_PeeringSync_FailsForTLSError(t *testing.T) {
|
||||||
func testLeader_PeeringSync_failsForTLSError(t *testing.T, tokenMutateFn func(token *structs.PeeringToken), expectErr string) {
|
func testLeader_PeeringSync_failsForTLSError(t *testing.T, tokenMutateFn func(token *structs.PeeringToken), expectErr string) {
|
||||||
require.NotNil(t, tokenMutateFn)
|
require.NotNil(t, tokenMutateFn)
|
||||||
|
|
||||||
|
ca := connect.TestCA(t, nil)
|
||||||
_, s1 := testServerWithConfig(t, func(c *Config) {
|
_, s1 := testServerWithConfig(t, func(c *Config) {
|
||||||
c.NodeName = "bob"
|
c.NodeName = "bob"
|
||||||
c.Datacenter = "dc1"
|
c.Datacenter = "dc1"
|
||||||
c.TLSConfig.Domain = "consul"
|
c.TLSConfig.Domain = "consul"
|
||||||
|
c.GRPCTLSPort = freeport.GetOne(t)
|
||||||
c.ConnectEnabled = false
|
c.CAConfig = &structs.CAConfiguration{
|
||||||
c.TLSConfig.GRPC.CAFile = "../../test/hostname/CertAuth.crt"
|
ClusterID: connect.TestClusterID,
|
||||||
c.TLSConfig.GRPC.CertFile = "../../test/hostname/Bob.crt"
|
Provider: structs.ConsulCAProvider,
|
||||||
c.TLSConfig.GRPC.KeyFile = "../../test/hostname/Bob.key"
|
Config: map[string]interface{}{
|
||||||
|
"PrivateKey": ca.SigningKey,
|
||||||
|
"RootCert": ca.RootCert,
|
||||||
|
},
|
||||||
|
}
|
||||||
})
|
})
|
||||||
testrpc.WaitForLeader(t, s1.RPC, "dc1")
|
testrpc.WaitForLeader(t, s1.RPC, "dc1")
|
||||||
|
|
||||||
|
@ -573,10 +538,6 @@ func testLeader_PeeringSync_failsForTLSError(t *testing.T, tokenMutateFn func(to
|
||||||
c.NodeName = "betty"
|
c.NodeName = "betty"
|
||||||
c.Datacenter = "dc2"
|
c.Datacenter = "dc2"
|
||||||
c.PrimaryDatacenter = "dc2"
|
c.PrimaryDatacenter = "dc2"
|
||||||
|
|
||||||
c.TLSConfig.GRPC.CAFile = "../../test/hostname/CertAuth.crt"
|
|
||||||
c.TLSConfig.GRPC.CertFile = "../../test/hostname/Betty.crt"
|
|
||||||
c.TLSConfig.GRPC.KeyFile = "../../test/hostname/Betty.key"
|
|
||||||
})
|
})
|
||||||
testrpc.WaitForLeader(t, s2.RPC, "dc2")
|
testrpc.WaitForLeader(t, s2.RPC, "dc2")
|
||||||
|
|
||||||
|
@ -615,11 +576,11 @@ func TestLeader_Peering_DeferredDeletion(t *testing.T) {
|
||||||
t.Skip("too slow for testing.Short")
|
t.Skip("too slow for testing.Short")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(peering): Configure with TLS
|
|
||||||
_, s1 := testServerWithConfig(t, func(c *Config) {
|
_, s1 := testServerWithConfig(t, func(c *Config) {
|
||||||
c.NodeName = "s1.dc1"
|
c.NodeName = "s1.dc1"
|
||||||
c.Datacenter = "dc1"
|
c.Datacenter = "dc1"
|
||||||
c.TLSConfig.Domain = "consul"
|
c.TLSConfig.Domain = "consul"
|
||||||
|
c.GRPCTLSPort = freeport.GetOne(t)
|
||||||
})
|
})
|
||||||
testrpc.WaitForLeader(t, s1.RPC, "dc1")
|
testrpc.WaitForLeader(t, s1.RPC, "dc1")
|
||||||
|
|
||||||
|
@ -694,15 +655,21 @@ func TestLeader_Peering_DialerReestablishesConnectionOnError(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reserve a gRPC port so we can restart the accepting server with the same port.
|
// Reserve a gRPC port so we can restart the accepting server with the same port.
|
||||||
ports := freeport.GetN(t, 1)
|
acceptingServerPort := freeport.GetOne(t)
|
||||||
acceptingServerPort := ports[0]
|
|
||||||
|
|
||||||
|
ca := connect.TestCA(t, nil)
|
||||||
_, acceptingServer := testServerWithConfig(t, func(c *Config) {
|
_, acceptingServer := testServerWithConfig(t, func(c *Config) {
|
||||||
c.NodeName = "acceptingServer.dc1"
|
c.NodeName = "acceptingServer.dc1"
|
||||||
c.Datacenter = "dc1"
|
c.Datacenter = "dc1"
|
||||||
c.TLSConfig.Domain = "consul"
|
c.GRPCTLSPort = acceptingServerPort
|
||||||
c.GRPCPort = acceptingServerPort
|
c.CAConfig = &structs.CAConfiguration{
|
||||||
c.PeeringEnabled = true
|
ClusterID: connect.TestClusterID,
|
||||||
|
Provider: structs.ConsulCAProvider,
|
||||||
|
Config: map[string]interface{}{
|
||||||
|
"PrivateKey": ca.SigningKey,
|
||||||
|
"RootCert": ca.RootCert,
|
||||||
|
},
|
||||||
|
}
|
||||||
})
|
})
|
||||||
testrpc.WaitForLeader(t, acceptingServer.RPC, "dc1")
|
testrpc.WaitForLeader(t, acceptingServer.RPC, "dc1")
|
||||||
|
|
||||||
|
@ -805,9 +772,17 @@ func TestLeader_Peering_DialerReestablishesConnectionOnError(t *testing.T) {
|
||||||
c.NodeName = "acceptingServer.dc1"
|
c.NodeName = "acceptingServer.dc1"
|
||||||
c.Datacenter = "dc1"
|
c.Datacenter = "dc1"
|
||||||
c.TLSConfig.Domain = "consul"
|
c.TLSConfig.Domain = "consul"
|
||||||
c.GRPCPort = acceptingServerPort
|
|
||||||
c.DataDir = acceptingServer.config.DataDir
|
c.DataDir = acceptingServer.config.DataDir
|
||||||
c.NodeID = acceptingServer.config.NodeID
|
c.NodeID = acceptingServer.config.NodeID
|
||||||
|
c.GRPCTLSPort = acceptingServerPort
|
||||||
|
c.CAConfig = &structs.CAConfiguration{
|
||||||
|
ClusterID: connect.TestClusterID,
|
||||||
|
Provider: structs.ConsulCAProvider,
|
||||||
|
Config: map[string]interface{}{
|
||||||
|
"PrivateKey": ca.SigningKey,
|
||||||
|
"RootCert": ca.RootCert,
|
||||||
|
},
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
testrpc.WaitForLeader(t, acceptingServerRestart.RPC, "dc1")
|
testrpc.WaitForLeader(t, acceptingServerRestart.RPC, "dc1")
|
||||||
|
@ -902,11 +877,19 @@ func TestLeader_Peering_ImportedExportedServicesCount(t *testing.T) {
|
||||||
t.Skip("too slow for testing.Short")
|
t.Skip("too slow for testing.Short")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ca := connect.TestCA(t, nil)
|
||||||
_, s1 := testServerWithConfig(t, func(c *Config) {
|
_, s1 := testServerWithConfig(t, func(c *Config) {
|
||||||
c.NodeName = "s1.dc1"
|
c.NodeName = "s1.dc1"
|
||||||
c.Datacenter = "dc1"
|
c.Datacenter = "dc1"
|
||||||
c.TLSConfig.Domain = "consul"
|
c.GRPCTLSPort = freeport.GetOne(t)
|
||||||
c.PeeringEnabled = true
|
c.CAConfig = &structs.CAConfiguration{
|
||||||
|
ClusterID: connect.TestClusterID,
|
||||||
|
Provider: structs.ConsulCAProvider,
|
||||||
|
Config: map[string]interface{}{
|
||||||
|
"PrivateKey": ca.SigningKey,
|
||||||
|
"RootCert": ca.RootCert,
|
||||||
|
},
|
||||||
|
}
|
||||||
})
|
})
|
||||||
testrpc.WaitForLeader(t, s1.RPC, "dc1")
|
testrpc.WaitForLeader(t, s1.RPC, "dc1")
|
||||||
|
|
||||||
|
@ -1204,11 +1187,19 @@ func TestLeader_PeeringMetrics_emitPeeringMetrics(t *testing.T) {
|
||||||
lastIdx = uint64(0)
|
lastIdx = uint64(0)
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO(peering): Configure with TLS
|
ca := connect.TestCA(t, nil)
|
||||||
_, s1 := testServerWithConfig(t, func(c *Config) {
|
_, s1 := testServerWithConfig(t, func(c *Config) {
|
||||||
c.NodeName = "s1.dc1"
|
c.NodeName = "s1.dc1"
|
||||||
c.Datacenter = "dc1"
|
c.Datacenter = "dc1"
|
||||||
c.TLSConfig.Domain = "consul"
|
c.GRPCTLSPort = freeport.GetOne(t)
|
||||||
|
c.CAConfig = &structs.CAConfiguration{
|
||||||
|
ClusterID: connect.TestClusterID,
|
||||||
|
Provider: structs.ConsulCAProvider,
|
||||||
|
Config: map[string]interface{}{
|
||||||
|
"PrivateKey": ca.SigningKey,
|
||||||
|
"RootCert": ca.RootCert,
|
||||||
|
},
|
||||||
|
}
|
||||||
})
|
})
|
||||||
testrpc.WaitForLeader(t, s1.RPC, "dc1")
|
testrpc.WaitForLeader(t, s1.RPC, "dc1")
|
||||||
|
|
||||||
|
@ -1615,10 +1606,20 @@ func Test_Leader_PeeringSync_ServerAddressUpdates(t *testing.T) {
|
||||||
maxRetryBackoff = 1
|
maxRetryBackoff = 1
|
||||||
t.Cleanup(func() { maxRetryBackoff = orig })
|
t.Cleanup(func() { maxRetryBackoff = orig })
|
||||||
|
|
||||||
|
ca := connect.TestCA(t, nil)
|
||||||
_, acceptor := testServerWithConfig(t, func(c *Config) {
|
_, acceptor := testServerWithConfig(t, func(c *Config) {
|
||||||
c.NodeName = "acceptor"
|
c.NodeName = "acceptor"
|
||||||
c.Datacenter = "dc1"
|
c.Datacenter = "dc1"
|
||||||
c.TLSConfig.Domain = "consul"
|
c.TLSConfig.Domain = "consul"
|
||||||
|
c.GRPCTLSPort = freeport.GetOne(t)
|
||||||
|
c.CAConfig = &structs.CAConfiguration{
|
||||||
|
ClusterID: connect.TestClusterID,
|
||||||
|
Provider: structs.ConsulCAProvider,
|
||||||
|
Config: map[string]interface{}{
|
||||||
|
"PrivateKey": ca.SigningKey,
|
||||||
|
"RootCert": ca.RootCert,
|
||||||
|
},
|
||||||
|
}
|
||||||
})
|
})
|
||||||
testrpc.WaitForLeader(t, acceptor.RPC, "dc1")
|
testrpc.WaitForLeader(t, acceptor.RPC, "dc1")
|
||||||
|
|
||||||
|
|
|
@ -57,26 +57,21 @@ func (b *PeeringBackend) GetLeaderAddress() string {
|
||||||
|
|
||||||
// GetTLSMaterials returns the TLS materials for the dialer to dial the acceptor using TLS.
|
// GetTLSMaterials returns the TLS materials for the dialer to dial the acceptor using TLS.
|
||||||
// It returns the server name to validate, and the CA certificate to validate with.
|
// It returns the server name to validate, and the CA certificate to validate with.
|
||||||
func (b *PeeringBackend) GetTLSMaterials() (string, []string, error) {
|
func (b *PeeringBackend) GetTLSMaterials(generatingToken bool) (string, []string, error) {
|
||||||
// Do not send TLS materials to the dialer if we to not have TLS configured for gRPC.
|
if generatingToken {
|
||||||
if b.srv.config.GRPCTLSPort <= 0 && !b.srv.tlsConfigurator.GRPCServerUseTLS() {
|
if !b.srv.config.ConnectEnabled {
|
||||||
return "", nil, nil
|
return "", nil, fmt.Errorf("connect.enabled must be set to true in the server's configuration when generating peering tokens")
|
||||||
}
|
}
|
||||||
|
if b.srv.config.GRPCTLSPort <= 0 && !b.srv.tlsConfigurator.GRPCServerUseTLS() {
|
||||||
// If the Connect CA is not in use we rely on the manually configured certs.
|
return "", nil, fmt.Errorf("TLS for gRPC must be enabled when generating peering tokens")
|
||||||
// Otherwise we rely on the internally managed server certificate.
|
}
|
||||||
if !b.srv.config.ConnectEnabled {
|
|
||||||
serverName := b.srv.tlsConfigurator.ServerSNI(b.srv.config.Datacenter, "")
|
|
||||||
caPems := b.srv.tlsConfigurator.GRPCManualCAPems()
|
|
||||||
|
|
||||||
return serverName, caPems, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
roots, err := b.srv.getCARoots(nil, b.srv.fsm.State())
|
roots, err := b.srv.getCARoots(nil, b.srv.fsm.State())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, fmt.Errorf("failed to fetch roots: %w", err)
|
return "", nil, fmt.Errorf("failed to fetch roots: %w", err)
|
||||||
}
|
}
|
||||||
if len(roots.Roots) == 0 {
|
if len(roots.Roots) == 0 || roots.TrustDomain == "" {
|
||||||
return "", nil, fmt.Errorf("CA has not finished initializing")
|
return "", nil, fmt.Errorf("CA has not finished initializing")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,10 @@ import (
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
gogrpc "google.golang.org/grpc"
|
gogrpc "google.golang.org/grpc"
|
||||||
|
|
||||||
|
"github.com/hashicorp/consul/agent/connect"
|
||||||
|
"github.com/hashicorp/consul/agent/structs"
|
||||||
"github.com/hashicorp/consul/proto/pbpeering"
|
"github.com/hashicorp/consul/proto/pbpeering"
|
||||||
|
"github.com/hashicorp/consul/sdk/freeport"
|
||||||
"github.com/hashicorp/consul/testrpc"
|
"github.com/hashicorp/consul/testrpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -21,9 +24,18 @@ func TestPeeringBackend_RejectsPartition(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
ca := connect.TestCA(t, nil)
|
||||||
_, s1 := testServerWithConfig(t, func(c *Config) {
|
_, s1 := testServerWithConfig(t, func(c *Config) {
|
||||||
c.Datacenter = "dc1"
|
c.GRPCTLSPort = freeport.GetOne(t)
|
||||||
c.Bootstrap = true
|
c.CAConfig = &structs.CAConfiguration{
|
||||||
|
ClusterID: connect.TestClusterID,
|
||||||
|
Provider: structs.ConsulCAProvider,
|
||||||
|
Config: map[string]interface{}{
|
||||||
|
"PrivateKey": ca.SigningKey,
|
||||||
|
"RootCert": ca.RootCert,
|
||||||
|
},
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
testrpc.WaitForLeader(t, s1.RPC, "dc1")
|
testrpc.WaitForLeader(t, s1.RPC, "dc1")
|
||||||
|
@ -55,9 +67,17 @@ func TestPeeringBackend_IgnoresDefaultPartition(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
ca := connect.TestCA(t, nil)
|
||||||
_, s1 := testServerWithConfig(t, func(c *Config) {
|
_, s1 := testServerWithConfig(t, func(c *Config) {
|
||||||
c.Datacenter = "dc1"
|
c.GRPCTLSPort = freeport.GetOne(t)
|
||||||
c.Bootstrap = true
|
c.CAConfig = &structs.CAConfiguration{
|
||||||
|
ClusterID: connect.TestClusterID,
|
||||||
|
Provider: structs.ConsulCAProvider,
|
||||||
|
Config: map[string]interface{}{
|
||||||
|
"PrivateKey": ca.SigningKey,
|
||||||
|
"RootCert": ca.RootCert,
|
||||||
|
},
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
testrpc.WaitForLeader(t, s1.RPC, "dc1")
|
testrpc.WaitForLeader(t, s1.RPC, "dc1")
|
||||||
|
|
|
@ -7,17 +7,18 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/hashicorp/consul/agent/structs"
|
|
||||||
"github.com/hashicorp/consul/sdk/freeport"
|
|
||||||
"github.com/hashicorp/consul/types"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
gogrpc "google.golang.org/grpc"
|
gogrpc "google.golang.org/grpc"
|
||||||
|
|
||||||
|
"github.com/hashicorp/consul/agent/connect"
|
||||||
"github.com/hashicorp/consul/agent/pool"
|
"github.com/hashicorp/consul/agent/pool"
|
||||||
|
"github.com/hashicorp/consul/agent/structs"
|
||||||
"github.com/hashicorp/consul/proto/pbpeering"
|
"github.com/hashicorp/consul/proto/pbpeering"
|
||||||
"github.com/hashicorp/consul/proto/pbpeerstream"
|
"github.com/hashicorp/consul/proto/pbpeerstream"
|
||||||
|
"github.com/hashicorp/consul/sdk/freeport"
|
||||||
"github.com/hashicorp/consul/sdk/testutil"
|
"github.com/hashicorp/consul/sdk/testutil"
|
||||||
"github.com/hashicorp/consul/testrpc"
|
"github.com/hashicorp/consul/testrpc"
|
||||||
|
"github.com/hashicorp/consul/types"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestPeeringBackend_ForwardToLeader(t *testing.T) {
|
func TestPeeringBackend_ForwardToLeader(t *testing.T) {
|
||||||
|
@ -25,17 +26,26 @@ func TestPeeringBackend_ForwardToLeader(t *testing.T) {
|
||||||
t.Skip("too slow for testing.Short")
|
t.Skip("too slow for testing.Short")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, conf1 := testServerConfig(t)
|
ca := connect.TestCA(t, nil)
|
||||||
server1, err := newServer(t, conf1)
|
_, server1 := testServerWithConfig(t, func(c *Config) {
|
||||||
require.NoError(t, err)
|
c.GRPCTLSPort = freeport.GetOne(t)
|
||||||
|
c.CAConfig = &structs.CAConfiguration{
|
||||||
_, conf2 := testServerConfig(t)
|
ClusterID: connect.TestClusterID,
|
||||||
conf2.Bootstrap = false
|
Provider: structs.ConsulCAProvider,
|
||||||
server2, err := newServer(t, conf2)
|
Config: map[string]interface{}{
|
||||||
require.NoError(t, err)
|
"PrivateKey": ca.SigningKey,
|
||||||
|
"RootCert": ca.RootCert,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
_, server2 := testServerWithConfig(t, func(c *Config) {
|
||||||
|
c.Bootstrap = false
|
||||||
|
})
|
||||||
|
|
||||||
// Join a 2nd server (not the leader)
|
// Join a 2nd server (not the leader)
|
||||||
testrpc.WaitForLeader(t, server1.RPC, "dc1")
|
testrpc.WaitForLeader(t, server1.RPC, "dc1")
|
||||||
|
testrpc.WaitForActiveCARoot(t, server1.RPC, "dc1", nil)
|
||||||
|
|
||||||
joinLAN(t, server2, server1)
|
joinLAN(t, server2, server1)
|
||||||
testrpc.WaitForLeader(t, server2.RPC, "dc1")
|
testrpc.WaitForLeader(t, server2.RPC, "dc1")
|
||||||
|
|
||||||
|
@ -166,17 +176,26 @@ func TestPeerStreamService_ForwardToLeader(t *testing.T) {
|
||||||
t.Skip("too slow for testing.Short")
|
t.Skip("too slow for testing.Short")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, conf1 := testServerConfig(t)
|
ca := connect.TestCA(t, nil)
|
||||||
server1, err := newServer(t, conf1)
|
_, server1 := testServerWithConfig(t, func(c *Config) {
|
||||||
require.NoError(t, err)
|
c.GRPCTLSPort = freeport.GetOne(t)
|
||||||
|
c.CAConfig = &structs.CAConfiguration{
|
||||||
_, conf2 := testServerConfig(t)
|
ClusterID: connect.TestClusterID,
|
||||||
conf2.Bootstrap = false
|
Provider: structs.ConsulCAProvider,
|
||||||
server2, err := newServer(t, conf2)
|
Config: map[string]interface{}{
|
||||||
require.NoError(t, err)
|
"PrivateKey": ca.SigningKey,
|
||||||
|
"RootCert": ca.RootCert,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
_, server2 := testServerWithConfig(t, func(c *Config) {
|
||||||
|
c.Bootstrap = false
|
||||||
|
})
|
||||||
|
|
||||||
// server1 is leader, server2 follower
|
// server1 is leader, server2 follower
|
||||||
testrpc.WaitForLeader(t, server1.RPC, "dc1")
|
testrpc.WaitForLeader(t, server1.RPC, "dc1")
|
||||||
|
testrpc.WaitForActiveCARoot(t, server1.RPC, "dc1", nil)
|
||||||
|
|
||||||
joinLAN(t, server2, server1)
|
joinLAN(t, server2, server1)
|
||||||
testrpc.WaitForLeader(t, server2.RPC, "dc1")
|
testrpc.WaitForLeader(t, server2.RPC, "dc1")
|
||||||
|
|
||||||
|
|
|
@ -21,12 +21,14 @@ import (
|
||||||
"github.com/hashicorp/consul-net-rpc/net/rpc"
|
"github.com/hashicorp/consul-net-rpc/net/rpc"
|
||||||
|
|
||||||
"github.com/hashicorp/consul/acl"
|
"github.com/hashicorp/consul/acl"
|
||||||
|
"github.com/hashicorp/consul/agent/connect"
|
||||||
grpcexternal "github.com/hashicorp/consul/agent/grpc-external"
|
grpcexternal "github.com/hashicorp/consul/agent/grpc-external"
|
||||||
"github.com/hashicorp/consul/agent/structs"
|
"github.com/hashicorp/consul/agent/structs"
|
||||||
"github.com/hashicorp/consul/agent/structs/aclfilter"
|
"github.com/hashicorp/consul/agent/structs/aclfilter"
|
||||||
tokenStore "github.com/hashicorp/consul/agent/token"
|
tokenStore "github.com/hashicorp/consul/agent/token"
|
||||||
"github.com/hashicorp/consul/api"
|
"github.com/hashicorp/consul/api"
|
||||||
"github.com/hashicorp/consul/proto/pbpeering"
|
"github.com/hashicorp/consul/proto/pbpeering"
|
||||||
|
"github.com/hashicorp/consul/sdk/freeport"
|
||||||
"github.com/hashicorp/consul/sdk/testutil/retry"
|
"github.com/hashicorp/consul/sdk/testutil/retry"
|
||||||
"github.com/hashicorp/consul/testrpc"
|
"github.com/hashicorp/consul/testrpc"
|
||||||
"github.com/hashicorp/consul/types"
|
"github.com/hashicorp/consul/types"
|
||||||
|
@ -1463,10 +1465,20 @@ func TestPreparedQuery_Execute(t *testing.T) {
|
||||||
|
|
||||||
s2.tokens.UpdateReplicationToken("root", tokenStore.TokenSourceConfig)
|
s2.tokens.UpdateReplicationToken("root", tokenStore.TokenSourceConfig)
|
||||||
|
|
||||||
|
ca := connect.TestCA(t, nil)
|
||||||
dir3, s3 := testServerWithConfig(t, func(c *Config) {
|
dir3, s3 := testServerWithConfig(t, func(c *Config) {
|
||||||
c.Datacenter = "dc3"
|
c.Datacenter = "dc3"
|
||||||
c.PrimaryDatacenter = "dc3"
|
c.PrimaryDatacenter = "dc3"
|
||||||
c.NodeName = "acceptingServer.dc3"
|
c.NodeName = "acceptingServer.dc3"
|
||||||
|
c.GRPCTLSPort = freeport.GetOne(t)
|
||||||
|
c.CAConfig = &structs.CAConfiguration{
|
||||||
|
ClusterID: connect.TestClusterID,
|
||||||
|
Provider: structs.ConsulCAProvider,
|
||||||
|
Config: map[string]interface{}{
|
||||||
|
"PrivateKey": ca.SigningKey,
|
||||||
|
"RootCert": ca.RootCert,
|
||||||
|
},
|
||||||
|
}
|
||||||
})
|
})
|
||||||
defer os.RemoveAll(dir3)
|
defer os.RemoveAll(dir3)
|
||||||
defer s3.Shutdown()
|
defer s3.Shutdown()
|
||||||
|
|
|
@ -43,7 +43,6 @@ import (
|
||||||
|
|
||||||
const (
|
const (
|
||||||
testPeerID = "caf067a6-f112-4907-9101-d45857d2b149"
|
testPeerID = "caf067a6-f112-4907-9101-d45857d2b149"
|
||||||
testActiveStreamSecretID = "e778c518-f0db-473a-9224-24b357da971d"
|
|
||||||
testPendingStreamSecretID = "522c0daf-2ef2-4dab-bc78-5e04e3daf552"
|
testPendingStreamSecretID = "522c0daf-2ef2-4dab-bc78-5e04e3daf552"
|
||||||
testEstablishmentSecretID = "f6569d37-1c5b-4415-aae5-26f4594f7f60"
|
testEstablishmentSecretID = "f6569d37-1c5b-4415-aae5-26f4594f7f60"
|
||||||
)
|
)
|
||||||
|
|
|
@ -116,7 +116,7 @@ type Backend interface {
|
||||||
|
|
||||||
// GetTLSMaterials returns the TLS materials for the dialer to dial the acceptor using TLS.
|
// GetTLSMaterials returns the TLS materials for the dialer to dial the acceptor using TLS.
|
||||||
// It returns the server name to validate, and the CA certificate to validate with.
|
// It returns the server name to validate, and the CA certificate to validate with.
|
||||||
GetTLSMaterials() (string, []string, error)
|
GetTLSMaterials(generatingToken bool) (string, []string, error)
|
||||||
|
|
||||||
// GetServerAddresses returns the addresses used for establishing a peering connection.
|
// GetServerAddresses returns the addresses used for establishing a peering connection.
|
||||||
// These may be server addresses or mesh gateway addresses if peering through mesh gateways.
|
// These may be server addresses or mesh gateway addresses if peering through mesh gateways.
|
||||||
|
@ -221,6 +221,11 @@ func (s *Server) GenerateToken(
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
serverName, caPEMs, err := s.Backend.GetTLSMaterials(true)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
peering *pbpeering.Peering
|
peering *pbpeering.Peering
|
||||||
secretID string
|
secretID string
|
||||||
|
@ -288,11 +293,6 @@ func (s *Server) GenerateToken(
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
serverName, caPEMs, err := s.Backend.GetTLSMaterials()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// ServerExternalAddresses must be formatted as addr:port.
|
// ServerExternalAddresses must be formatted as addr:port.
|
||||||
var serverAddrs []string
|
var serverAddrs []string
|
||||||
if len(req.ServerExternalAddresses) > 0 {
|
if len(req.ServerExternalAddresses) > 0 {
|
||||||
|
@ -484,12 +484,12 @@ func (s *Server) validatePeeringLocality(token *structs.PeeringToken, partition
|
||||||
|
|
||||||
// If the token has the same server name as this cluster, but we can't find the peering
|
// If the token has the same server name as this cluster, but we can't find the peering
|
||||||
// in our store, it indicates a naming conflict.
|
// in our store, it indicates a naming conflict.
|
||||||
serverName, _, err := s.Backend.GetTLSMaterials()
|
serverName, _, err := s.Backend.GetTLSMaterials(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to fetch TLS materials: %w", err)
|
return fmt.Errorf("failed to fetch TLS materials: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if serverName != "" && token.ServerName != "" && serverName == token.ServerName && peering == nil {
|
if serverName == token.ServerName && peering == nil {
|
||||||
return fmt.Errorf("conflict - peering token's server name matches the current cluster's server name, %q, but there is no record in the database", serverName)
|
return fmt.Errorf("conflict - peering token's server name matches the current cluster's server name, %q, but there is no record in the database", serverName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -398,7 +398,7 @@ func TestPeeringService_Establish_serverNameConflict(t *testing.T) {
|
||||||
id, err := uuid.GenerateUUID()
|
id, err := uuid.GenerateUUID()
|
||||||
require.NoError(t, err, "could not generate uuid")
|
require.NoError(t, err, "could not generate uuid")
|
||||||
|
|
||||||
serverName, _, err := s.Server.GetPeeringBackend().GetTLSMaterials()
|
serverName, _, err := s.Server.GetPeeringBackend().GetTLSMaterials(true)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
peeringToken := structs.PeeringToken{
|
peeringToken := structs.PeeringToken{
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
primary_datacenter = "primary"
|
primary_datacenter = "primary"
|
||||||
log_level = "trace"
|
log_level = "trace"
|
|
@ -0,0 +1,6 @@
|
||||||
|
ports {
|
||||||
|
grpc_tls = 8503
|
||||||
|
}
|
||||||
|
connect {
|
||||||
|
enabled = true
|
||||||
|
}
|
|
@ -104,6 +104,13 @@ function init_workdir {
|
||||||
mv workdir/${CLUSTER}/consul/server.hcl workdir/${CLUSTER}/consul-server/server.hcl
|
mv workdir/${CLUSTER}/consul/server.hcl workdir/${CLUSTER}/consul-server/server.hcl
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test -f "workdir/${CLUSTER}/consul/peering_server.hcl" -a $REQUIRE_PEERS = "1"
|
||||||
|
then
|
||||||
|
mv workdir/${CLUSTER}/consul/peering_server.hcl workdir/${CLUSTER}/consul-server/peering_server.hcl
|
||||||
|
else
|
||||||
|
rm workdir/${CLUSTER}/consul/peering_server.hcl
|
||||||
|
fi
|
||||||
|
|
||||||
# copy the ca-certs for SDS so we can verify the right ones are served
|
# copy the ca-certs for SDS so we can verify the right ones are served
|
||||||
mkdir -p workdir/test-sds-server/certs
|
mkdir -p workdir/test-sds-server/certs
|
||||||
cp test-sds-server/certs/ca-root.crt workdir/test-sds-server/certs/ca-root.crt
|
cp test-sds-server/certs/ca-root.crt workdir/test-sds-server/certs/ca-root.crt
|
||||||
|
@ -216,11 +223,6 @@ function start_consul {
|
||||||
docker_kill_rm consul-${DC}-server
|
docker_kill_rm consul-${DC}-server
|
||||||
docker_kill_rm consul-${DC}
|
docker_kill_rm consul-${DC}
|
||||||
|
|
||||||
server_grpc_port="-1"
|
|
||||||
if is_set $REQUIRE_PEERS; then
|
|
||||||
server_grpc_port="8502"
|
|
||||||
fi
|
|
||||||
|
|
||||||
docker run -d --name envoy_consul-${DC}-server_1 \
|
docker run -d --name envoy_consul-${DC}-server_1 \
|
||||||
--net=envoy-tests \
|
--net=envoy-tests \
|
||||||
$WORKDIR_SNIPPET \
|
$WORKDIR_SNIPPET \
|
||||||
|
@ -231,7 +233,6 @@ function start_consul {
|
||||||
agent -dev -datacenter "${DC}" \
|
agent -dev -datacenter "${DC}" \
|
||||||
-config-dir "/workdir/${DC}/consul" \
|
-config-dir "/workdir/${DC}/consul" \
|
||||||
-config-dir "/workdir/${DC}/consul-server" \
|
-config-dir "/workdir/${DC}/consul-server" \
|
||||||
-grpc-port $server_grpc_port \
|
|
||||||
-client "0.0.0.0" \
|
-client "0.0.0.0" \
|
||||||
-bind "0.0.0.0" >/dev/null
|
-bind "0.0.0.0" >/dev/null
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue