124 lines
4.5 KiB
Go
124 lines
4.5 KiB
Go
|
//+build !ent
|
||
|
|
||
|
package nomad
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"errors"
|
||
|
"testing"
|
||
|
|
||
|
"github.com/hashicorp/nomad/command/agent/consul"
|
||
|
"github.com/hashicorp/nomad/helper/testlog"
|
||
|
"github.com/hashicorp/nomad/nomad/structs"
|
||
|
"github.com/stretchr/testify/require"
|
||
|
)
|
||
|
|
||
|
func TestConsulACLsAPI_CheckPermissions_oss(t *testing.T) {
|
||
|
|
||
|
// In Nomad OSS, CheckPermissions will only receive "" as input for the
|
||
|
// namespace parameter - as the ConsulUsage map from namespace to usages will
|
||
|
// always contain one key - the empty string.
|
||
|
|
||
|
t.Parallel()
|
||
|
|
||
|
try := func(t *testing.T, namespace string, usage *structs.ConsulUsage, secretID string, exp error) {
|
||
|
logger := testlog.HCLogger(t)
|
||
|
aclAPI := consul.NewMockACLsAPI(logger)
|
||
|
cAPI := NewConsulACLsAPI(aclAPI, logger, nil)
|
||
|
|
||
|
err := cAPI.CheckPermissions(context.Background(), namespace, usage, secretID)
|
||
|
if exp == nil {
|
||
|
require.NoError(t, err)
|
||
|
} else {
|
||
|
require.Equal(t, exp.Error(), err.Error())
|
||
|
}
|
||
|
}
|
||
|
|
||
|
t.Run("check-permissions kv read", func(t *testing.T) {
|
||
|
t.Run("uses kv has permission", func(t *testing.T) {
|
||
|
u := &structs.ConsulUsage{KV: true}
|
||
|
try(t, "", u, consul.ExampleOperatorTokenID5, nil)
|
||
|
})
|
||
|
|
||
|
t.Run("uses kv without permission", func(t *testing.T) {
|
||
|
u := &structs.ConsulUsage{KV: true}
|
||
|
try(t, "", u, consul.ExampleOperatorTokenID1, errors.New("insufficient Consul ACL permissions to use template"))
|
||
|
})
|
||
|
|
||
|
t.Run("uses kv no token", func(t *testing.T) {
|
||
|
u := &structs.ConsulUsage{KV: true}
|
||
|
try(t, "", u, "", errors.New("missing consul token"))
|
||
|
})
|
||
|
|
||
|
t.Run("uses kv nonsense token", func(t *testing.T) {
|
||
|
u := &structs.ConsulUsage{KV: true}
|
||
|
try(t, "", u, "47d33e22-720a-7fe6-7d7f-418bf844a0be", errors.New("unable to read consul token: no such token"))
|
||
|
})
|
||
|
|
||
|
t.Run("no kv no token", func(t *testing.T) {
|
||
|
u := &structs.ConsulUsage{KV: false}
|
||
|
try(t, "", u, "", nil)
|
||
|
})
|
||
|
})
|
||
|
|
||
|
t.Run("check-permissions service write", func(t *testing.T) {
|
||
|
usage := &structs.ConsulUsage{Services: []string{"service1"}}
|
||
|
|
||
|
t.Run("operator has service write", func(t *testing.T) {
|
||
|
try(t, "", usage, consul.ExampleOperatorTokenID1, nil)
|
||
|
})
|
||
|
|
||
|
t.Run("operator has service_prefix write", func(t *testing.T) {
|
||
|
u := &structs.ConsulUsage{Services: []string{"foo-service1"}}
|
||
|
try(t, "", u, consul.ExampleOperatorTokenID2, nil)
|
||
|
})
|
||
|
|
||
|
t.Run("operator has service_prefix write wrong prefix", func(t *testing.T) {
|
||
|
u := &structs.ConsulUsage{Services: []string{"bar-service1"}}
|
||
|
try(t, "", u, consul.ExampleOperatorTokenID2, errors.New(`insufficient Consul ACL permissions to write service "bar-service1"`))
|
||
|
})
|
||
|
|
||
|
t.Run("operator permissions insufficient", func(t *testing.T) {
|
||
|
try(t, "", usage, consul.ExampleOperatorTokenID3, errors.New(`insufficient Consul ACL permissions to write service "service1"`))
|
||
|
})
|
||
|
|
||
|
t.Run("operator provided no token", func(t *testing.T) {
|
||
|
try(t, "", usage, "", errors.New("missing consul token"))
|
||
|
})
|
||
|
|
||
|
t.Run("operator provided nonsense token", func(t *testing.T) {
|
||
|
try(t, "", usage, "f1682bde-1e71-90b1-9204-85d35467ba61", errors.New("unable to read consul token: no such token"))
|
||
|
})
|
||
|
})
|
||
|
|
||
|
t.Run("check-permissions connect service identity write", func(t *testing.T) {
|
||
|
usage := &structs.ConsulUsage{Kinds: []structs.TaskKind{structs.NewTaskKind(structs.ConnectProxyPrefix, "service1")}}
|
||
|
|
||
|
t.Run("operator has service write", func(t *testing.T) {
|
||
|
try(t, "", usage, consul.ExampleOperatorTokenID1, nil)
|
||
|
})
|
||
|
|
||
|
t.Run("operator has service_prefix write", func(t *testing.T) {
|
||
|
u := &structs.ConsulUsage{Kinds: []structs.TaskKind{structs.NewTaskKind(structs.ConnectProxyPrefix, "foo-service1")}}
|
||
|
try(t, "", u, consul.ExampleOperatorTokenID2, nil)
|
||
|
})
|
||
|
|
||
|
t.Run("operator has service_prefix write wrong prefix", func(t *testing.T) {
|
||
|
u := &structs.ConsulUsage{Kinds: []structs.TaskKind{structs.NewTaskKind(structs.ConnectProxyPrefix, "bar-service1")}}
|
||
|
try(t, "", u, consul.ExampleOperatorTokenID2, errors.New(`insufficient Consul ACL permissions to write Connect service "bar-service1"`))
|
||
|
})
|
||
|
|
||
|
t.Run("operator permissions insufficient", func(t *testing.T) {
|
||
|
try(t, "", usage, consul.ExampleOperatorTokenID3, errors.New(`insufficient Consul ACL permissions to write Connect service "service1"`))
|
||
|
})
|
||
|
|
||
|
t.Run("operator provided no token", func(t *testing.T) {
|
||
|
try(t, "", usage, "", errors.New("missing consul token"))
|
||
|
})
|
||
|
|
||
|
t.Run("operator provided nonsense token", func(t *testing.T) {
|
||
|
try(t, "", usage, "f1682bde-1e71-90b1-9204-85d35467ba61", errors.New("unable to read consul token: no such token"))
|
||
|
})
|
||
|
})
|
||
|
}
|