2023-05-26 19:22:54 +00:00
|
|
|
// Copyright (c) HashiCorp, Inc.
|
2023-08-11 13:12:13 +00:00
|
|
|
// SPDX-License-Identifier: BUSL-1.1
|
2023-05-26 19:22:54 +00:00
|
|
|
|
|
|
|
package extauthz
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/hashicorp/consul/api"
|
|
|
|
"github.com/hashicorp/consul/envoyextensions/extensioncommon"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestConstructor(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
cases := map[string]struct {
|
|
|
|
extName string
|
|
|
|
args map[string]any
|
|
|
|
errMsg string
|
|
|
|
}{
|
|
|
|
"invalid name": {
|
|
|
|
extName: "invalid",
|
|
|
|
errMsg: `expected extension name "builtin/ext-authz"`,
|
|
|
|
},
|
|
|
|
"invalid proxy type": {
|
|
|
|
args: map[string]any{"ProxyType": "invalid"},
|
|
|
|
errMsg: `unsupported ProxyType`,
|
|
|
|
},
|
|
|
|
"no service type": {
|
|
|
|
args: map[string]any{"ProxyType": "connect-proxy"},
|
|
|
|
errMsg: `exactly one of GrpcService or HttpService must be set`,
|
|
|
|
},
|
|
|
|
"both service types": {
|
|
|
|
args: map[string]any{
|
|
|
|
"ProxyType": "connect-proxy",
|
|
|
|
"Config": map[string]any{
|
|
|
|
"GrpcService": map[string]any{
|
|
|
|
"Target": map[string]any{
|
|
|
|
"URI": "localhost:9191",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"HttpService": map[string]any{
|
|
|
|
"Target": map[string]any{
|
|
|
|
"URI": "localhost:9191",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
errMsg: `exactly one of GrpcService or HttpService must be set`,
|
|
|
|
},
|
|
|
|
"non-loopback address hostname": {
|
|
|
|
args: map[string]any{
|
|
|
|
"ProxyType": "connect-proxy",
|
|
|
|
"Config": map[string]any{
|
|
|
|
"GrpcService": map[string]any{
|
|
|
|
"Target": map[string]any{
|
|
|
|
"URI": "foo.bar.com:9191",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2023-06-21 20:42:42 +00:00
|
|
|
errMsg: `invalid host for Target.URI "foo.bar.com:9191": expected "localhost", "127.0.0.1", or "::1"`,
|
2023-05-26 19:22:54 +00:00
|
|
|
},
|
|
|
|
"non-loopback address": {
|
|
|
|
args: map[string]any{
|
|
|
|
"ProxyType": "connect-proxy",
|
|
|
|
"Config": map[string]any{
|
|
|
|
"GrpcService": map[string]any{
|
|
|
|
"Target": map[string]any{
|
|
|
|
"URI": "10.0.0.1:9191",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2023-06-21 20:42:42 +00:00
|
|
|
errMsg: `invalid host for Target.URI "10.0.0.1:9191": expected "localhost", "127.0.0.1", or "::1"`,
|
|
|
|
},
|
|
|
|
"invalid target port": {
|
|
|
|
args: map[string]any{
|
|
|
|
"ProxyType": "connect-proxy",
|
|
|
|
"Config": map[string]any{
|
|
|
|
"GrpcService": map[string]any{
|
|
|
|
"Target": map[string]any{
|
|
|
|
"URI": "localhost:zero",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
errMsg: `invalid format for Target.URI "localhost:zero": expected host:port`,
|
|
|
|
},
|
|
|
|
"invalid target timeout": {
|
|
|
|
args: map[string]any{
|
|
|
|
"ProxyType": "connect-proxy",
|
|
|
|
"Config": map[string]any{
|
|
|
|
"GrpcService": map[string]any{
|
|
|
|
"Target": map[string]any{
|
|
|
|
"URI": "localhost:9191",
|
|
|
|
"Timeout": "one",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
errMsg: `failed to parse Target.Timeout "one" as a duration`,
|
2023-05-26 19:22:54 +00:00
|
|
|
},
|
|
|
|
"no uri or service target": {
|
|
|
|
args: map[string]any{
|
|
|
|
"ProxyType": "connect-proxy",
|
|
|
|
"Config": map[string]any{
|
|
|
|
"HttpService": map[string]any{
|
|
|
|
"Target": map[string]any{
|
|
|
|
"Timeout": "1s",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
errMsg: `exactly one of Target.Service or Target.URI must be set`,
|
|
|
|
},
|
|
|
|
"uri and service target": {
|
|
|
|
args: map[string]any{
|
|
|
|
"ProxyType": "connect-proxy",
|
|
|
|
"Config": map[string]any{
|
|
|
|
"GrpcService": map[string]any{
|
|
|
|
"Target": map[string]any{
|
|
|
|
"URI": "10.0.0.1:9191",
|
|
|
|
"Service": map[string]any{
|
|
|
|
"Name": "test-service",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
errMsg: `exactly one of Target.Service or Target.URI must be set`,
|
|
|
|
},
|
|
|
|
"invalid status on error": {
|
|
|
|
args: map[string]any{
|
|
|
|
"ProxyType": "connect-proxy",
|
|
|
|
"Config": map[string]any{
|
|
|
|
"StatusOnError": 1,
|
|
|
|
"GrpcService": map[string]any{
|
|
|
|
"Target": map[string]any{
|
|
|
|
"URI": "10.0.0.1:9191",
|
|
|
|
"Service": map[string]any{
|
|
|
|
"Name": "test-service",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
errMsg: `failed to validate Config.StatusOnError`,
|
|
|
|
},
|
|
|
|
"valid grpc service": {
|
|
|
|
args: map[string]any{
|
|
|
|
"ProxyType": "connect-proxy",
|
|
|
|
"Config": map[string]any{
|
|
|
|
"GrpcService": map[string]any{
|
|
|
|
"Target": map[string]any{
|
|
|
|
"URI": "localhost:9191",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"valid http service": {
|
|
|
|
args: map[string]any{
|
|
|
|
"ProxyType": "connect-proxy",
|
|
|
|
"Config": map[string]any{
|
|
|
|
"HttpService": map[string]any{
|
|
|
|
"Target": map[string]any{
|
|
|
|
"URI": "127.0.0.1:9191",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for name, c := range cases {
|
|
|
|
c := c
|
|
|
|
t.Run(name, func(t *testing.T) {
|
|
|
|
extName := api.BuiltinExtAuthzExtension
|
|
|
|
if c.extName != "" {
|
|
|
|
extName = c.extName
|
|
|
|
}
|
|
|
|
ext, err := newExtAuthz(api.EnvoyExtension{Name: extName, Arguments: c.args})
|
|
|
|
if c.errMsg == "" {
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
httpFilter, err := ext.Config.toEnvoyHttpFilter(&extensioncommon.RuntimeConfig{})
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, httpFilter)
|
|
|
|
|
|
|
|
if ext.Config.isGRPC() {
|
|
|
|
netFilter, err := ext.Config.toEnvoyNetworkFilter(&extensioncommon.RuntimeConfig{})
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, netFilter)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
require.Error(t, err)
|
|
|
|
require.Contains(t, err.Error(), c.errMsg)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|