mirror of https://github.com/status-im/consul.git
parent
24e9603d9b
commit
ab8f23478a
|
@ -10,6 +10,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
"github.com/testcontainers/testcontainers-go"
|
||||||
|
|
||||||
libcluster "github.com/hashicorp/consul/test/integration/consul-container/libs/cluster"
|
libcluster "github.com/hashicorp/consul/test/integration/consul-container/libs/cluster"
|
||||||
libtopology "github.com/hashicorp/consul/test/integration/consul-container/libs/topology"
|
libtopology "github.com/hashicorp/consul/test/integration/consul-container/libs/topology"
|
||||||
|
@ -17,58 +18,88 @@ import (
|
||||||
|
|
||||||
const (
|
const (
|
||||||
RESOURCE_FILE_PATH_ON_HOST = "../../../../../command/resource/testdata/demo.hcl"
|
RESOURCE_FILE_PATH_ON_HOST = "../../../../../command/resource/testdata/demo.hcl"
|
||||||
|
CLIENT_CERT_ON_HOST = "../../../../client_certs/client.crt"
|
||||||
|
CLIENT_KEY_ON_HOST = "../../../../client_certs/client.key"
|
||||||
|
ROOT_CA_ON_HOST = "../../../../client_certs/rootca.crt"
|
||||||
RESOURCE_FILE_PATH_ON_CONTAINER = "/consul/data/demo.hcl"
|
RESOURCE_FILE_PATH_ON_CONTAINER = "/consul/data/demo.hcl"
|
||||||
|
CLIENT_CERT_ON_CONTAINER = "/consul/data/client.crt"
|
||||||
|
CLIENT_KEY_ON_CONTAINER = "/consul/data/client.key"
|
||||||
|
ROOT_CA_ON_CONTAINER = "/consul/data/rootca.crt"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestClientForwardToServer(t *testing.T) {
|
func TestClientForwardToServer(t *testing.T) {
|
||||||
type operation struct {
|
type operation struct {
|
||||||
action func(*testing.T, libcluster.Agent, string) (int, string)
|
action func(*testing.T, libcluster.Agent, string, bool) (int, string)
|
||||||
includeToken bool
|
includeToken bool
|
||||||
expectedCode int
|
expectedCode int
|
||||||
expectedMsg string
|
expectedMsg string
|
||||||
}
|
}
|
||||||
type testCase struct {
|
type testCase struct {
|
||||||
description string
|
description string
|
||||||
operations []operation
|
operation operation
|
||||||
aclEnabled bool
|
aclEnabled bool
|
||||||
|
tlsEnabled bool
|
||||||
|
verifyIncoming bool
|
||||||
}
|
}
|
||||||
|
|
||||||
testCases := []testCase{
|
testCases := []testCase{
|
||||||
{
|
{
|
||||||
description: "The apply request should be forwarded to consul server agent",
|
description: "The apply request should be forwarded to consul server agent",
|
||||||
operations: []operation{
|
operation: operation{
|
||||||
{
|
|
||||||
action: applyResource,
|
action: applyResource,
|
||||||
includeToken: false,
|
includeToken: false,
|
||||||
expectedCode: 0,
|
expectedCode: 0,
|
||||||
expectedMsg: "demo.v2.Artist 'korn' created.",
|
expectedMsg: "demo.v2.Artist 'korn' created.",
|
||||||
},
|
},
|
||||||
},
|
|
||||||
aclEnabled: false,
|
aclEnabled: false,
|
||||||
|
tlsEnabled: false,
|
||||||
|
verifyIncoming: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description: "The apply request should be denied if missing token when ACL is enabled",
|
description: "The apply request should be denied if missing token when ACL is enabled",
|
||||||
operations: []operation{
|
operation: operation{
|
||||||
{
|
|
||||||
action: applyResource,
|
action: applyResource,
|
||||||
includeToken: false,
|
includeToken: false,
|
||||||
expectedCode: 1,
|
expectedCode: 1,
|
||||||
expectedMsg: "failed getting authorizer: ACL not found",
|
expectedMsg: "failed getting authorizer: ACL not found",
|
||||||
},
|
},
|
||||||
},
|
|
||||||
aclEnabled: true,
|
aclEnabled: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description: "The apply request should be allowed if providing token when ACL is enabled",
|
description: "The apply request should be allowed if providing token when ACL is enabled",
|
||||||
operations: []operation{
|
operation: operation{
|
||||||
{
|
|
||||||
action: applyResource,
|
action: applyResource,
|
||||||
includeToken: true,
|
includeToken: true,
|
||||||
expectedCode: 0,
|
expectedCode: 0,
|
||||||
expectedMsg: "demo.v2.Artist 'korn' created.",
|
expectedMsg: "demo.v2.Artist 'korn' created.",
|
||||||
},
|
},
|
||||||
},
|
|
||||||
aclEnabled: true,
|
aclEnabled: true,
|
||||||
|
tlsEnabled: false,
|
||||||
|
verifyIncoming: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "The apply request should be forwarded to consul server agent when server is in TLS mode",
|
||||||
|
operation: operation{
|
||||||
|
action: applyResource,
|
||||||
|
includeToken: false,
|
||||||
|
expectedCode: 0,
|
||||||
|
expectedMsg: "demo.v2.Artist 'korn' created.",
|
||||||
|
},
|
||||||
|
aclEnabled: false,
|
||||||
|
tlsEnabled: true,
|
||||||
|
verifyIncoming: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "The apply request should be forwarded to consul server agent when server and client are in TLS mode",
|
||||||
|
operation: operation{
|
||||||
|
action: applyResource,
|
||||||
|
includeToken: false,
|
||||||
|
expectedCode: 0,
|
||||||
|
expectedMsg: "demo.v2.Artist 'korn' created.",
|
||||||
|
},
|
||||||
|
aclEnabled: false,
|
||||||
|
tlsEnabled: true,
|
||||||
|
verifyIncoming: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,53 +109,74 @@ func TestClientForwardToServer(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
var clientAgent libcluster.Agent
|
var clientAgent libcluster.Agent
|
||||||
cluster, clientAgent := setupClusterAndClient(t, tc.aclEnabled)
|
cluster, clientAgent := setupClusterAndClient(t, tc.aclEnabled, tc.tlsEnabled, tc.verifyIncoming)
|
||||||
defer terminate(t, cluster)
|
defer terminate(t, cluster)
|
||||||
|
|
||||||
// perform actions and validate returned messages
|
// perform actions and validate returned messages
|
||||||
for _, op := range tc.operations {
|
|
||||||
token := ""
|
token := ""
|
||||||
if op.includeToken {
|
if tc.operation.includeToken {
|
||||||
token = cluster.TokenBootstrap
|
token = cluster.TokenBootstrap
|
||||||
}
|
}
|
||||||
code, res := op.action(t, clientAgent, token)
|
code, res := tc.operation.action(t, clientAgent, token, tc.verifyIncoming)
|
||||||
require.Equal(t, op.expectedCode, code)
|
require.Equal(t, tc.operation.expectedCode, code)
|
||||||
require.Contains(t, res, op.expectedMsg)
|
require.Contains(t, res, tc.operation.expectedMsg)
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func applyResource(t *testing.T, clientAgent libcluster.Agent, token string) (int, string) {
|
func applyResource(t *testing.T, clientAgent libcluster.Agent, token string, verifyIncoming bool) (int, string) {
|
||||||
ctx := context.Background()
|
|
||||||
c := clientAgent.GetConsulContainer()
|
c := clientAgent.GetConsulContainer()
|
||||||
err := c.CopyFileToContainer(ctx, RESOURCE_FILE_PATH_ON_HOST, RESOURCE_FILE_PATH_ON_CONTAINER, 700)
|
copyFilesToContainer(t, c, verifyIncoming)
|
||||||
require.NoError(t, err)
|
|
||||||
args := []string{"/bin/consul", "resource", "apply", fmt.Sprintf("-f=%s", RESOURCE_FILE_PATH_ON_CONTAINER)}
|
args := []string{"/bin/consul", "resource", "apply", fmt.Sprintf("-f=%s", RESOURCE_FILE_PATH_ON_CONTAINER)}
|
||||||
if token != "" {
|
if token != "" {
|
||||||
args = append(args, fmt.Sprintf("-token=%s", token))
|
args = append(args, fmt.Sprintf("-token=%s", token))
|
||||||
}
|
}
|
||||||
code, reader, err := c.Exec(ctx, args)
|
if verifyIncoming {
|
||||||
|
args = append(
|
||||||
|
args,
|
||||||
|
"-grpc-tls=true",
|
||||||
|
"-grpc-addr=127.0.0.1:8503",
|
||||||
|
fmt.Sprintf("-client-cert=%s", CLIENT_CERT_ON_CONTAINER),
|
||||||
|
fmt.Sprintf("-client-key=%s", CLIENT_KEY_ON_CONTAINER),
|
||||||
|
fmt.Sprintf("-ca-file=%s", ROOT_CA_ON_CONTAINER),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
code, reader, err := c.Exec(context.Background(), args)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
buf, err := io.ReadAll(reader)
|
buf, err := io.ReadAll(reader)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return code, string(buf)
|
return code, string(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
// passing two cmd args to set up the cluster
|
func copyFilesToContainer(t *testing.T, c testcontainers.Container, verifyIncoming bool) {
|
||||||
func setupClusterAndClient(t *testing.T, aclEnabled bool) (*libcluster.Cluster, libcluster.Agent) {
|
err := c.CopyFileToContainer(context.Background(), RESOURCE_FILE_PATH_ON_HOST, RESOURCE_FILE_PATH_ON_CONTAINER, 700)
|
||||||
|
require.NoError(t, err)
|
||||||
|
if verifyIncoming {
|
||||||
|
err = c.CopyFileToContainer(context.Background(), CLIENT_CERT_ON_HOST, CLIENT_CERT_ON_CONTAINER, 700)
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = c.CopyFileToContainer(context.Background(), CLIENT_KEY_ON_HOST, CLIENT_KEY_ON_CONTAINER, 700)
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = c.CopyFileToContainer(context.Background(), ROOT_CA_ON_HOST, ROOT_CA_ON_CONTAINER, 700)
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func setupClusterAndClient(t *testing.T, aclEnabled bool, tlsEnabled bool, verifyIncoming bool) (*libcluster.Cluster, libcluster.Agent) {
|
||||||
clusterConfig := &libtopology.ClusterConfig{
|
clusterConfig := &libtopology.ClusterConfig{
|
||||||
NumServers: 1,
|
NumServers: 1,
|
||||||
NumClients: 1,
|
NumClients: 1,
|
||||||
LogConsumer: &libtopology.TestLogConsumer{},
|
LogConsumer: &libtopology.TestLogConsumer{},
|
||||||
BuildOpts: &libcluster.BuildOptions{
|
BuildOpts: &libcluster.BuildOptions{
|
||||||
Datacenter: "dc1",
|
Datacenter: "dc1",
|
||||||
InjectAutoEncryption: true,
|
InjectAutoEncryption: tlsEnabled,
|
||||||
InjectGossipEncryption: true,
|
UseGRPCWithTLS: tlsEnabled,
|
||||||
ACLEnabled: aclEnabled,
|
ACLEnabled: aclEnabled,
|
||||||
},
|
},
|
||||||
ApplyDefaultProxySettings: false,
|
ApplyDefaultProxySettings: false,
|
||||||
}
|
}
|
||||||
|
if verifyIncoming {
|
||||||
|
clusterConfig.Cmd = "-hcl=tls { defaults { verify_incoming = true } }"
|
||||||
|
}
|
||||||
cluster, _, _ := libtopology.NewCluster(t, clusterConfig)
|
cluster, _, _ := libtopology.NewCluster(t, clusterConfig)
|
||||||
|
|
||||||
return cluster, cluster.Clients()[0]
|
return cluster, cluster.Clients()[0]
|
||||||
|
|
Loading…
Reference in New Issue