Files
nomad/e2e/acl/acl_role_test.go
Tim Gross ff928a8045 E2E: remove assertion from ACL role test (#19121)
The ACL role test asserts that the role has various permissions by listing jobs
in namespaces. It never creates jobs, because we can make all the assertions we
need by checking the error. But the test included an assertion that the
namespace was empty. Usually this will be the case, but if the previous test
case has not completed its GC (which is sync), then it's possible a stopped job
will be in the namespace. Because this assertion is irrelevant for this test,
remove it.
2023-11-17 14:35:20 -05:00

155 lines
5.6 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package acl
import (
"fmt"
"testing"
"github.com/hashicorp/nomad/api"
"github.com/hashicorp/nomad/e2e/e2eutil"
"github.com/hashicorp/nomad/helper/uuid"
"github.com/shoenig/test/must"
)
// testACLRole tests basic functionality of ACL roles when used for
// authorization. It also performs some basic token and policy tests due to the
// coupling between the ACL objects.
func testACLRole(t *testing.T) {
nomadClient := e2eutil.NomadClient(t)
// 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)
// 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
// that does not exist.
invalidRole := api.ACLRole{
Name: "e2e-acl-" + uuid.Short(),
Description: "E2E ACL Role Testing",
Policies: []*api.ACLRolePolicyLink{{Name: "404-not-found"}},
}
aclRoleCreateResp, _, err := nomadClient.ACLRoles().Create(&invalidRole, nil)
must.ErrorContains(t, err, "cannot find policy 404-not-found")
must.Nil(t, aclRoleCreateResp)
// Create a custom namespace to test along with the default.
ns := api.Namespace{
Name: "e2e-acl-" + uuid.Short(),
Description: "E2E ACL Role Testing",
}
_, err = nomadClient.Namespaces().Register(&ns, nil)
must.NoError(t, err)
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.
customNamespacePolicy := api.ACLPolicy{
Name: "e2e-acl-" + uuid.Short(),
Description: "E2E ACL Role Testing",
Rules: fmt.Sprintf(`namespace %q {policy = "read"}`, ns.Name),
}
_, err = nomadClient.ACLPolicies().Upsert(&customNamespacePolicy, nil)
must.NoError(t, err)
cleanUpProcess.Add(customNamespacePolicy.Name, ACLPolicyTestResourceType)
// Create a valid role with a link to the previously created policy.
validRole := api.ACLRole{
Name: "e2e-acl-" + uuid.Short(),
Description: "E2E ACL Role Testing",
Policies: []*api.ACLRolePolicyLink{{Name: customNamespacePolicy.Name}},
}
aclRoleCreateResp, _, err = nomadClient.ACLRoles().Create(&validRole, nil)
must.NoError(t, err)
must.NotNil(t, aclRoleCreateResp)
must.NotEq(t, "", aclRoleCreateResp.ID)
must.Eq(t, validRole.Name, aclRoleCreateResp.Name)
cleanUpProcess.Add(aclRoleCreateResp.ID, ACLRoleTestResourceType)
// Perform a role listing and check we have the expected entries.
aclRoleListResp, _, err := nomadClient.ACLRoles().List(nil)
must.NoError(t, err)
must.Len(t, 1, aclRoleListResp)
must.Eq(t, aclRoleCreateResp.ID, aclRoleListResp[0].ID)
// Create our ACL token which is linked to the created ACL role.
token := api.ACLToken{
Name: "e2e-acl-" + uuid.Short(),
Type: "client",
Roles: []*api.ACLTokenRoleLink{{ID: aclRoleCreateResp.ID}},
}
aclTokenCreateResp, _, err := nomadClient.ACLTokens().Create(&token, nil)
must.NoError(t, err)
must.NotNil(t, aclTokenCreateResp)
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
// error.
customNSQueryMeta := api.QueryOptions{Namespace: ns.Name, AuthToken: aclTokenCreateResp.SecretID}
defaultNSQueryMeta := api.QueryOptions{Namespace: "default", AuthToken: aclTokenCreateResp.SecretID}
_, _, err = nomadClient.Jobs().List(&customNSQueryMeta)
must.NoError(t, err)
_, _, err = nomadClient.Jobs().List(&defaultNSQueryMeta)
must.ErrorContains(t, err, "Permission denied")
// Create an ACL policy which grants read access to the default namespace.
defaultNamespacePolicy := api.ACLPolicy{
Name: "e2e-acl-" + uuid.Short(),
Description: "E2E ACL Role Testing",
Rules: `namespace "default" {policy = "read"}`,
}
_, err = nomadClient.ACLPolicies().Upsert(&defaultNamespacePolicy, nil)
must.NoError(t, err)
cleanUpProcess.Add(defaultNamespacePolicy.Name, ACLPolicyTestResourceType)
// Update the ACL role to include the new ACL policy that allows read
// access to the default namespace.
aclRoleCreateResp.Policies = append(aclRoleCreateResp.Policies, &api.ACLRolePolicyLink{
Name: defaultNamespacePolicy.Name,
})
aclRoleUpdateResp, _, err := nomadClient.ACLRoles().Update(aclRoleCreateResp, nil)
must.NoError(t, err)
must.Eq(t, aclRoleCreateResp.ID, aclRoleUpdateResp.ID)
must.Len(t, 2, aclRoleUpdateResp.Policies)
// Try listing the jobs in the default namespace again to ensure we now
// have permission due to the updated role.
_, _, err = nomadClient.Jobs().List(&defaultNSQueryMeta)
must.NoError(t, err)
// Delete a policy from under the role.
_, err = nomadClient.ACLPolicies().Delete(defaultNamespacePolicy.Name, nil)
must.NoError(t, err)
cleanUpProcess.Remove(defaultNamespacePolicy.Name, ACLPolicyTestResourceType)
// The permission to list the job in the default namespace should now be
// revoked.
_, _, err = nomadClient.Jobs().List(&defaultNSQueryMeta)
must.ErrorContains(t, err, "Permission denied")
// Delete the ACL role.
_, err = nomadClient.ACLRoles().Delete(aclRoleUpdateResp.ID, nil)
must.NoError(t, err)
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.
_, _, err = nomadClient.Jobs().List(&customNSQueryMeta)
must.ErrorContains(t, err, "Permission denied")
}