mirror of https://github.com/status-im/consul.git
141 lines
5.1 KiB
Go
141 lines
5.1 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
package dataplane
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/hashicorp/go-hclog"
|
|
mock "github.com/stretchr/testify/mock"
|
|
"github.com/stretchr/testify/require"
|
|
"google.golang.org/grpc/codes"
|
|
"google.golang.org/grpc/status"
|
|
|
|
"github.com/hashicorp/consul/acl"
|
|
resolver "github.com/hashicorp/consul/acl/resolver"
|
|
external "github.com/hashicorp/consul/agent/grpc-external"
|
|
"github.com/hashicorp/consul/agent/grpc-external/testutils"
|
|
structs "github.com/hashicorp/consul/agent/structs"
|
|
"github.com/hashicorp/consul/proto-public/pbdataplane"
|
|
"github.com/hashicorp/consul/version"
|
|
)
|
|
|
|
const testACLToken = "acl-token"
|
|
|
|
func TestSupportedDataplaneFeatures_Success(t *testing.T) {
|
|
// Mock the ACL Resolver to return an authorizer with `service:write`.
|
|
aclResolver := &MockACLResolver{}
|
|
aclResolver.On("ResolveTokenAndDefaultMeta", testACLToken, mock.Anything, mock.Anything).
|
|
Return(testutils.ACLServiceWriteAny(t), nil)
|
|
|
|
options := structs.QueryOptions{Token: testACLToken}
|
|
ctx, err := external.ContextWithQueryOptions(context.Background(), options)
|
|
require.NoError(t, err)
|
|
|
|
server := NewServer(Config{
|
|
Logger: hclog.NewNullLogger(),
|
|
ACLResolver: aclResolver,
|
|
})
|
|
client := testClient(t, server)
|
|
resp, err := client.GetSupportedDataplaneFeatures(ctx, &pbdataplane.GetSupportedDataplaneFeaturesRequest{})
|
|
require.NoError(t, err)
|
|
require.Equal(t, 4, len(resp.SupportedDataplaneFeatures))
|
|
|
|
for _, feature := range resp.SupportedDataplaneFeatures {
|
|
switch feature.GetFeatureName() {
|
|
case pbdataplane.DataplaneFeatures_DATAPLANE_FEATURES_EDGE_CERTIFICATE_MANAGEMENT:
|
|
require.True(t, feature.GetSupported())
|
|
case pbdataplane.DataplaneFeatures_DATAPLANE_FEATURES_WATCH_SERVERS:
|
|
require.True(t, feature.GetSupported())
|
|
case pbdataplane.DataplaneFeatures_DATAPLANE_FEATURES_ENVOY_BOOTSTRAP_CONFIGURATION:
|
|
require.True(t, feature.GetSupported())
|
|
case pbdataplane.DataplaneFeatures_DATAPLANE_FEATURES_FIPS:
|
|
require.Equal(t, version.IsFIPS(), feature.GetSupported())
|
|
default:
|
|
require.False(t, feature.GetSupported())
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSupportedDataplaneFeatures_ACLsDisabled(t *testing.T) {
|
|
aclResolver := &MockACLResolver{}
|
|
aclResolver.On("ResolveTokenAndDefaultMeta", "", mock.Anything, mock.Anything).
|
|
Return(testutils.ACLsDisabled(t), nil)
|
|
|
|
options := structs.QueryOptions{Token: ""}
|
|
ctx, err := external.ContextWithQueryOptions(context.Background(), options)
|
|
require.NoError(t, err)
|
|
|
|
server := NewServer(Config{
|
|
Logger: hclog.NewNullLogger(),
|
|
ACLResolver: aclResolver,
|
|
})
|
|
client := testClient(t, server)
|
|
resp, err := client.GetSupportedDataplaneFeatures(ctx, &pbdataplane.GetSupportedDataplaneFeaturesRequest{})
|
|
require.NoError(t, err)
|
|
require.Equal(t, 4, len(resp.SupportedDataplaneFeatures))
|
|
}
|
|
|
|
func TestSupportedDataplaneFeatures_InvalidACLToken(t *testing.T) {
|
|
// Mock the ACL resolver to return ErrNotFound.
|
|
aclResolver := &MockACLResolver{}
|
|
aclResolver.On("ResolveTokenAndDefaultMeta", mock.Anything, mock.Anything, mock.Anything).
|
|
Return(resolver.Result{}, acl.ErrNotFound)
|
|
|
|
options := structs.QueryOptions{Token: testACLToken}
|
|
ctx, err := external.ContextWithQueryOptions(context.Background(), options)
|
|
require.NoError(t, err)
|
|
|
|
server := NewServer(Config{
|
|
Logger: hclog.NewNullLogger(),
|
|
ACLResolver: aclResolver,
|
|
})
|
|
client := testClient(t, server)
|
|
resp, err := client.GetSupportedDataplaneFeatures(ctx, &pbdataplane.GetSupportedDataplaneFeaturesRequest{})
|
|
require.Error(t, err)
|
|
require.Equal(t, codes.Unauthenticated.String(), status.Code(err).String())
|
|
require.Nil(t, resp)
|
|
}
|
|
|
|
func TestSupportedDataplaneFeatures_AnonymousACLToken(t *testing.T) {
|
|
// Mock the ACL resolver to return ErrNotFound.
|
|
aclResolver := &MockACLResolver{}
|
|
aclResolver.On("ResolveTokenAndDefaultMeta", mock.Anything, mock.Anything, mock.Anything).
|
|
Return(testutils.ACLAnonymous(t), nil)
|
|
|
|
options := structs.QueryOptions{Token: testACLToken}
|
|
ctx, err := external.ContextWithQueryOptions(context.Background(), options)
|
|
require.NoError(t, err)
|
|
|
|
server := NewServer(Config{
|
|
Logger: hclog.NewNullLogger(),
|
|
ACLResolver: aclResolver,
|
|
})
|
|
client := testClient(t, server)
|
|
resp, err := client.GetSupportedDataplaneFeatures(ctx, &pbdataplane.GetSupportedDataplaneFeaturesRequest{})
|
|
require.Error(t, err)
|
|
require.Equal(t, codes.Unauthenticated.String(), status.Code(err).String())
|
|
require.Nil(t, resp)
|
|
}
|
|
|
|
func TestSupportedDataplaneFeatures_NoPermissions(t *testing.T) {
|
|
// Mock the ACL resolver to return a deny all authorizer
|
|
aclResolver := &MockACLResolver{}
|
|
aclResolver.On("ResolveTokenAndDefaultMeta", testACLToken, mock.Anything, mock.Anything).
|
|
Return(testutils.ACLNoPermissions(t), nil)
|
|
|
|
options := structs.QueryOptions{Token: testACLToken}
|
|
ctx, err := external.ContextWithQueryOptions(context.Background(), options)
|
|
require.NoError(t, err)
|
|
|
|
server := NewServer(Config{
|
|
Logger: hclog.NewNullLogger(),
|
|
ACLResolver: aclResolver,
|
|
})
|
|
client := testClient(t, server)
|
|
_, err = client.GetSupportedDataplaneFeatures(ctx, &pbdataplane.GetSupportedDataplaneFeaturesRequest{})
|
|
require.NoError(t, err)
|
|
}
|