e2e/acl: export ACL resource Cleanup helpers (#16822)
The e2e/acl package has some nice helpers for tracking and cleaning up ACL objects, but they are currently private. Export them so I can abuse them in other e2e tests.
This commit is contained in:
parent
9dfe4aa7c0
commit
4b7cd0a651
|
@ -17,11 +17,11 @@ func testACLRole(t *testing.T) {
|
|||
|
||||
nomadClient := e2eutil.NomadClient(t)
|
||||
|
||||
// Create and defer the cleanup process. This is used to remove all
|
||||
// Create and defer the Cleanup process. This is used to remove all
|
||||
// resources created by this test and covers situations where the test
|
||||
// fails or during normal running.
|
||||
cleanUpProcess := newCleanup()
|
||||
defer cleanUpProcess.run(t, nomadClient)
|
||||
cleanUpProcess := NewCleanup()
|
||||
defer cleanUpProcess.Run(t, nomadClient)
|
||||
|
||||
// An ACL role must reference an ACL policy that is stored in state. Ensure
|
||||
// this behaviour by attempting to create a role that links to a policy
|
||||
|
@ -43,7 +43,7 @@ func testACLRole(t *testing.T) {
|
|||
_, err = nomadClient.Namespaces().Register(&ns, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
cleanUpProcess.add(ns.Name, namespaceTestResourceType)
|
||||
cleanUpProcess.Add(ns.Name, NamespaceTestResourceType)
|
||||
|
||||
// Create an ACL policy which will be used to link from the role. This
|
||||
// policy grants read access to our custom namespace.
|
||||
|
@ -55,7 +55,7 @@ func testACLRole(t *testing.T) {
|
|||
_, err = nomadClient.ACLPolicies().Upsert(&customNamespacePolicy, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
cleanUpProcess.add(customNamespacePolicy.Name, aclPolicyTestResourceType)
|
||||
cleanUpProcess.Add(customNamespacePolicy.Name, ACLPolicyTestResourceType)
|
||||
|
||||
// Create a valid role with a link to the previously created policy.
|
||||
validRole := api.ACLRole{
|
||||
|
@ -69,7 +69,7 @@ func testACLRole(t *testing.T) {
|
|||
require.NotEmpty(t, aclRoleCreateResp.ID)
|
||||
require.Equal(t, validRole.Name, aclRoleCreateResp.Name)
|
||||
|
||||
cleanUpProcess.add(aclRoleCreateResp.ID, aclRoleTestResourceType)
|
||||
cleanUpProcess.Add(aclRoleCreateResp.ID, ACLRoleTestResourceType)
|
||||
|
||||
// Perform a role listing and check we have the expected entries.
|
||||
aclRoleListResp, _, err := nomadClient.ACLRoles().List(nil)
|
||||
|
@ -87,7 +87,7 @@ func testACLRole(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
require.NotNil(t, aclTokenCreateResp)
|
||||
|
||||
cleanUpProcess.add(aclTokenCreateResp.AccessorID, aclTokenTestResourceType)
|
||||
cleanUpProcess.Add(aclTokenCreateResp.AccessorID, ACLTokenTestResourceType)
|
||||
|
||||
// Attempt two job listings against the two available namespaces. The token
|
||||
// only has access to the custom namespace, so the default should return an
|
||||
|
@ -111,7 +111,7 @@ func testACLRole(t *testing.T) {
|
|||
_, err = nomadClient.ACLPolicies().Upsert(&defaultNamespacePolicy, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
cleanUpProcess.add(defaultNamespacePolicy.Name, aclPolicyTestResourceType)
|
||||
cleanUpProcess.Add(defaultNamespacePolicy.Name, ACLPolicyTestResourceType)
|
||||
|
||||
// Update the ACL role to include the new ACL policy that allows read
|
||||
// access to the default namespace.
|
||||
|
@ -133,7 +133,7 @@ func testACLRole(t *testing.T) {
|
|||
_, err = nomadClient.ACLPolicies().Delete(defaultNamespacePolicy.Name, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
cleanUpProcess.remove(defaultNamespacePolicy.Name, aclPolicyTestResourceType)
|
||||
cleanUpProcess.Remove(defaultNamespacePolicy.Name, ACLPolicyTestResourceType)
|
||||
|
||||
// The permission to list the job in the default namespace should now be
|
||||
// revoked.
|
||||
|
@ -144,7 +144,7 @@ func testACLRole(t *testing.T) {
|
|||
_, err = nomadClient.ACLRoles().Delete(aclRoleUpdateResp.ID, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
cleanUpProcess.remove(aclRoleUpdateResp.ID, aclRoleTestResourceType)
|
||||
cleanUpProcess.Remove(aclRoleUpdateResp.ID, ACLRoleTestResourceType)
|
||||
|
||||
// We should now not be able to list jobs in the custom namespace either as
|
||||
// the token does not have any permissions.
|
||||
|
|
|
@ -3,11 +3,7 @@ package acl
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/go-set"
|
||||
"github.com/hashicorp/nomad/api"
|
||||
"github.com/hashicorp/nomad/e2e/e2eutil"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestACL(t *testing.T) {
|
||||
|
@ -25,93 +21,3 @@ func TestACL(t *testing.T) {
|
|||
t.Run("TestACL_TokenExpiration", testACLTokenExpiration)
|
||||
t.Run("TestACL_TokenRolePolicyAssignment", testACLTokenRolePolicyAssignment)
|
||||
}
|
||||
|
||||
// testResourceType indicates what the resource is so the cleanup process can
|
||||
// use the correct API.
|
||||
type testResourceType int
|
||||
|
||||
const (
|
||||
namespaceTestResourceType testResourceType = iota
|
||||
aclPolicyTestResourceType
|
||||
aclRoleTestResourceType
|
||||
aclTokenTestResourceType
|
||||
)
|
||||
|
||||
// cleanup stores Nomad resources that have been created by a test which will
|
||||
// need to be deleted once the test exits. This ensures other tests can run in
|
||||
// a clean environment and reduces the potential for conflicts.
|
||||
type cleanup struct {
|
||||
namespaces *set.Set[string]
|
||||
aclPolicies *set.Set[string]
|
||||
aclRoles *set.Set[string]
|
||||
aclTokens *set.Set[string]
|
||||
}
|
||||
|
||||
// newCleanup generates an initialized cleanup object for immediate use.
|
||||
func newCleanup() *cleanup {
|
||||
return &cleanup{
|
||||
namespaces: set.New[string](0),
|
||||
aclPolicies: set.New[string](0),
|
||||
aclRoles: set.New[string](0),
|
||||
aclTokens: set.New[string](0),
|
||||
}
|
||||
}
|
||||
|
||||
// run triggers a cleanup of all the stored resources. This should typically be
|
||||
// called via defer, so it will always run no matter if the test fails or not.
|
||||
// Any failure will ultimately fail the test, but will not stop the attempts to
|
||||
// delete all the resources.
|
||||
func (c *cleanup) run(t *testing.T, nomadClient *api.Client) {
|
||||
|
||||
for _, namespace := range c.namespaces.List() {
|
||||
_, err := nomadClient.Namespaces().Delete(namespace, nil)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
for _, policy := range c.aclPolicies.List() {
|
||||
_, err := nomadClient.ACLPolicies().Delete(policy, nil)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
for _, role := range c.aclRoles.List() {
|
||||
_, err := nomadClient.ACLRoles().Delete(role, nil)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
for _, token := range c.aclTokens.List() {
|
||||
_, err := nomadClient.ACLTokens().Delete(token, nil)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
require.NoError(t, nomadClient.System().GarbageCollect())
|
||||
}
|
||||
|
||||
// add the resource identifier to the resource tracker. It will be removed by
|
||||
// the cleanup function once it is triggered.
|
||||
func (c *cleanup) add(id string, resourceType testResourceType) {
|
||||
switch resourceType {
|
||||
case namespaceTestResourceType:
|
||||
c.namespaces.Insert(id)
|
||||
case aclPolicyTestResourceType:
|
||||
c.aclPolicies.Insert(id)
|
||||
case aclRoleTestResourceType:
|
||||
c.aclRoles.Insert(id)
|
||||
case aclTokenTestResourceType:
|
||||
c.aclTokens.Insert(id)
|
||||
}
|
||||
}
|
||||
|
||||
// remove the resource identifier from the resource tracker, indicating it is
|
||||
// no longer existing on the cluster and does not need to be cleaned.
|
||||
func (c *cleanup) remove(id string, resourceType testResourceType) {
|
||||
switch resourceType {
|
||||
case namespaceTestResourceType:
|
||||
c.namespaces.Remove(id)
|
||||
case aclPolicyTestResourceType:
|
||||
c.aclPolicies.Remove(id)
|
||||
case aclRoleTestResourceType:
|
||||
c.aclRoles.Remove(id)
|
||||
case aclTokenTestResourceType:
|
||||
c.aclTokens.Remove(id)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,11 +30,11 @@ func testACLTokenExpiration(t *testing.T) {
|
|||
|
||||
nomadClient := e2eutil.NomadClient(t)
|
||||
|
||||
// Create and defer the cleanup process. This is used to remove all
|
||||
// Create and defer the Cleanup process. This is used to remove all
|
||||
// resources created by this test and covers situations where the test
|
||||
// fails or during normal running.
|
||||
cleanUpProcess := newCleanup()
|
||||
defer cleanUpProcess.run(t, nomadClient)
|
||||
cleanUpProcess := NewCleanup()
|
||||
defer cleanUpProcess.Run(t, nomadClient)
|
||||
|
||||
// Create an ACL policy which will be assigned to the created ACL tokens.
|
||||
customNamespacePolicy := api.ACLPolicy{
|
||||
|
@ -45,7 +45,7 @@ func testACLTokenExpiration(t *testing.T) {
|
|||
_, err := nomadClient.ACLPolicies().Upsert(&customNamespacePolicy, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
cleanUpProcess.add(customNamespacePolicy.Name, aclPolicyTestResourceType)
|
||||
cleanUpProcess.Add(customNamespacePolicy.Name, ACLPolicyTestResourceType)
|
||||
|
||||
// Create our default query options which can be used when testing a token
|
||||
// against the API. The caller should update the auth token as needed.
|
||||
|
@ -92,7 +92,7 @@ func testACLTokenExpiration(t *testing.T) {
|
|||
*tokenNormalExpiryCreateResp.ExpirationTime,
|
||||
tokenNormalExpiryCreateResp.CreateTime.Add(tokenNormalExpiryCreateResp.ExpirationTTL))
|
||||
|
||||
cleanUpProcess.add(tokenNormalExpiryCreateResp.AccessorID, aclTokenTestResourceType)
|
||||
cleanUpProcess.Add(tokenNormalExpiryCreateResp.AccessorID, ACLTokenTestResourceType)
|
||||
|
||||
// Add the token to our query options and ensure we can now list jobs with
|
||||
// the default namespace.
|
||||
|
@ -116,7 +116,7 @@ func testACLTokenExpiration(t *testing.T) {
|
|||
*tokenQuickExpiryCreateResp.ExpirationTime,
|
||||
tokenQuickExpiryCreateResp.CreateTime.Add(tokenQuickExpiryCreateResp.ExpirationTTL))
|
||||
|
||||
cleanUpProcess.add(tokenQuickExpiryCreateResp.AccessorID, aclTokenTestResourceType)
|
||||
cleanUpProcess.Add(tokenQuickExpiryCreateResp.AccessorID, ACLTokenTestResourceType)
|
||||
|
||||
// Block the test (sorry) until the token has expired.
|
||||
time.Sleep(tokenQuickExpiry.ExpirationTTL)
|
||||
|
@ -129,7 +129,7 @@ func testACLTokenExpiration(t *testing.T) {
|
|||
require.ErrorContains(t, err, "ACL token expired")
|
||||
require.Nil(t, jobListResp)
|
||||
|
||||
cleanUpProcess.remove(tokenQuickExpiryCreateResp.AccessorID, aclTokenTestResourceType)
|
||||
cleanUpProcess.Remove(tokenQuickExpiryCreateResp.AccessorID, ACLTokenTestResourceType)
|
||||
|
||||
// List the tokens to ensure the output correctly shows the token
|
||||
// expiration. Other tests may have left tokens in state, so do not perform
|
||||
|
@ -164,7 +164,7 @@ func testACLTokenExpiration(t *testing.T) {
|
|||
require.ErrorContains(t, err, "ACL token not found")
|
||||
require.Nil(t, tokenNormalExpiryReadResp)
|
||||
|
||||
cleanUpProcess.remove(tokenNormalExpiryCreateResp.AccessorID, aclTokenTestResourceType)
|
||||
cleanUpProcess.Remove(tokenNormalExpiryCreateResp.AccessorID, ACLTokenTestResourceType)
|
||||
}
|
||||
|
||||
// testACLTokenRolePolicyAssignment tests that tokens allow and have the
|
||||
|
@ -174,11 +174,11 @@ func testACLTokenRolePolicyAssignment(t *testing.T) {
|
|||
|
||||
nomadClient := e2eutil.NomadClient(t)
|
||||
|
||||
// Create and defer the cleanup process. This is used to remove all
|
||||
// Create and defer the Cleanup process. This is used to remove all
|
||||
// resources created by this test and covers situations where the test
|
||||
// fails or during normal running.
|
||||
cleanUpProcess := newCleanup()
|
||||
defer cleanUpProcess.run(t, nomadClient)
|
||||
cleanUpProcess := NewCleanup()
|
||||
defer cleanUpProcess.Run(t, nomadClient)
|
||||
|
||||
// Create two ACL policies which will be used throughout this test. One
|
||||
// grants read access to the default namespace, the other grants read
|
||||
|
@ -191,7 +191,7 @@ func testACLTokenRolePolicyAssignment(t *testing.T) {
|
|||
_, err := nomadClient.ACLPolicies().Upsert(&defaultNamespacePolicy, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
cleanUpProcess.add(defaultNamespacePolicy.Name, aclPolicyTestResourceType)
|
||||
cleanUpProcess.Add(defaultNamespacePolicy.Name, ACLPolicyTestResourceType)
|
||||
|
||||
nodePolicy := api.ACLPolicy{
|
||||
Name: "e2e-acl-" + uuid.Short(),
|
||||
|
@ -201,7 +201,7 @@ func testACLTokenRolePolicyAssignment(t *testing.T) {
|
|||
_, err = nomadClient.ACLPolicies().Upsert(&nodePolicy, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
cleanUpProcess.add(nodePolicy.Name, aclPolicyTestResourceType)
|
||||
cleanUpProcess.Add(nodePolicy.Name, ACLPolicyTestResourceType)
|
||||
|
||||
// Create an ACL role that has the node read policy assigned.
|
||||
aclRole := api.ACLRole{
|
||||
|
@ -214,7 +214,7 @@ func testACLTokenRolePolicyAssignment(t *testing.T) {
|
|||
require.NotNil(t, aclRoleCreateResp)
|
||||
require.NotEmpty(t, aclRoleCreateResp.ID)
|
||||
|
||||
cleanUpProcess.add(aclRoleCreateResp.ID, aclRoleTestResourceType)
|
||||
cleanUpProcess.Add(aclRoleCreateResp.ID, ACLRoleTestResourceType)
|
||||
|
||||
// Create an ACL token which only has the ACL policy which allows reading
|
||||
// the default namespace assigned.
|
||||
|
@ -228,7 +228,7 @@ func testACLTokenRolePolicyAssignment(t *testing.T) {
|
|||
require.NotNil(t, aclTokenCreateResp)
|
||||
require.NotEmpty(t, aclTokenCreateResp.SecretID)
|
||||
|
||||
cleanUpProcess.add(aclTokenCreateResp.AccessorID, aclTokenTestResourceType)
|
||||
cleanUpProcess.Add(aclTokenCreateResp.AccessorID, ACLTokenTestResourceType)
|
||||
|
||||
// Test that the token can read the default namespace, but that it cannot
|
||||
// read node objects.
|
||||
|
@ -291,7 +291,7 @@ func testACLTokenRolePolicyAssignment(t *testing.T) {
|
|||
require.NotNil(t, aclTokenCreateResp)
|
||||
require.NotEmpty(t, aclTokenCreateResp.SecretID)
|
||||
|
||||
cleanUpProcess.add(aclTokenCreateResp.AccessorID, aclTokenTestResourceType)
|
||||
cleanUpProcess.Add(aclTokenCreateResp.AccessorID, ACLTokenTestResourceType)
|
||||
|
||||
// Test that the token is working as expected.
|
||||
defaultNSQueryMeta.AuthToken = aclTokenCreateResp.SecretID
|
||||
|
@ -308,11 +308,11 @@ func testACLTokenRolePolicyAssignment(t *testing.T) {
|
|||
// remove the assignment.
|
||||
_, err = nomadClient.ACLPolicies().Delete(defaultNamespacePolicy.Name, nil)
|
||||
require.NoError(t, err)
|
||||
cleanUpProcess.remove(defaultNamespacePolicy.Name, aclPolicyTestResourceType)
|
||||
cleanUpProcess.Remove(defaultNamespacePolicy.Name, ACLPolicyTestResourceType)
|
||||
|
||||
_, err = nomadClient.ACLRoles().Delete(aclRoleCreateResp.ID, nil)
|
||||
require.NoError(t, err)
|
||||
cleanUpProcess.remove(aclRoleCreateResp.ID, aclRoleTestResourceType)
|
||||
cleanUpProcess.Remove(aclRoleCreateResp.ID, ACLRoleTestResourceType)
|
||||
|
||||
// The token now should not have any power here; quite different to
|
||||
// Gandalf's power over the spell on King Theoden.
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
package acl
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/go-set"
|
||||
"github.com/hashicorp/nomad/api"
|
||||
"github.com/shoenig/test"
|
||||
"github.com/shoenig/test/must"
|
||||
)
|
||||
|
||||
// TestResourceType indicates what the resource is so the Cleanup process can
|
||||
// use the correct API.
|
||||
type TestResourceType int
|
||||
|
||||
const (
|
||||
NamespaceTestResourceType TestResourceType = iota
|
||||
ACLPolicyTestResourceType
|
||||
ACLRoleTestResourceType
|
||||
ACLTokenTestResourceType
|
||||
)
|
||||
|
||||
// Cleanup stores Nomad resources that have been created by a test which will
|
||||
// need to be deleted once the test exits. This ensures other tests can run in
|
||||
// a clean environment and reduces the potential for conflicts.
|
||||
type Cleanup struct {
|
||||
namespaces *set.Set[string]
|
||||
aclPolicies *set.Set[string]
|
||||
aclRoles *set.Set[string]
|
||||
aclTokens *set.Set[string]
|
||||
}
|
||||
|
||||
// NewCleanup generates an initialized Cleanup object for immediate use.
|
||||
func NewCleanup() *Cleanup {
|
||||
return &Cleanup{
|
||||
namespaces: set.New[string](0),
|
||||
aclPolicies: set.New[string](0),
|
||||
aclRoles: set.New[string](0),
|
||||
aclTokens: set.New[string](0),
|
||||
}
|
||||
}
|
||||
|
||||
// Run triggers a Cleanup of all the stored resources. This should typically be
|
||||
// called via defer, so it will always Run no matter if the test fails or not.
|
||||
// Any failure will ultimately fail the test, but will not stop the attempts to
|
||||
// delete all the resources.
|
||||
func (c *Cleanup) Run(t *testing.T, nomadClient *api.Client) {
|
||||
for _, namespace := range c.namespaces.Slice() {
|
||||
_, err := nomadClient.Namespaces().Delete(namespace, nil)
|
||||
test.NoError(t, err)
|
||||
}
|
||||
|
||||
for _, policy := range c.aclPolicies.Slice() {
|
||||
_, err := nomadClient.ACLPolicies().Delete(policy, nil)
|
||||
test.NoError(t, err)
|
||||
}
|
||||
|
||||
for _, role := range c.aclRoles.Slice() {
|
||||
_, err := nomadClient.ACLRoles().Delete(role, nil)
|
||||
test.NoError(t, err)
|
||||
}
|
||||
|
||||
for _, token := range c.aclTokens.Slice() {
|
||||
_, err := nomadClient.ACLTokens().Delete(token, nil)
|
||||
test.NoError(t, err)
|
||||
}
|
||||
|
||||
must.NoError(t, nomadClient.System().GarbageCollect())
|
||||
}
|
||||
|
||||
// Add the resource identifier to the resource tracker. It will be removed by
|
||||
// the Cleanup function once it is triggered.
|
||||
func (c *Cleanup) Add(id string, resourceType TestResourceType) {
|
||||
switch resourceType {
|
||||
case NamespaceTestResourceType:
|
||||
c.namespaces.Insert(id)
|
||||
case ACLPolicyTestResourceType:
|
||||
c.aclPolicies.Insert(id)
|
||||
case ACLRoleTestResourceType:
|
||||
c.aclRoles.Insert(id)
|
||||
case ACLTokenTestResourceType:
|
||||
c.aclTokens.Insert(id)
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the resource identifier from the resource tracker, indicating it is
|
||||
// no longer existing on the cluster and does not need to be cleaned.
|
||||
func (c *Cleanup) Remove(id string, resourceType TestResourceType) {
|
||||
switch resourceType {
|
||||
case NamespaceTestResourceType:
|
||||
c.namespaces.Remove(id)
|
||||
case ACLPolicyTestResourceType:
|
||||
c.aclPolicies.Remove(id)
|
||||
case ACLRoleTestResourceType:
|
||||
c.aclRoles.Remove(id)
|
||||
case ACLTokenTestResourceType:
|
||||
c.aclTokens.Remove(id)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue